2008-09-26 75 views
3

我有一個微型迷你搜索引擎,突出顯示了我的rails應用程序中的搜索條件。搜索忽略重音,高亮區不區分大小寫。幾乎完美。 但是,例如,如果我有文本「pãode queijo」並搜索「pao de queijo」的記錄,則記錄返回,但文本不是突出顯示。同樣,如果我搜索「páde queijo」記錄將返回但不正確突出顯示。如何忽略突出顯示功能中的重音

我的代碼很簡單,只要:

<%= highlight(result_pessoa.observacoes, search_string, '<span style="background-color: yellow;">\1</span>') %> 

回答

3

我剛剛提交了一個補丁來解決這個問題。

http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/3593-patch-support-for-highlighting-with-ignoring-special-chars

# Highlights one or more +phrases+ everywhere in +text+ by inserting it into 
    # a <tt>:highlighter</tt> string. The highlighter can be specialized by passing <tt>:highlighter</tt> 
    # as a single-quoted string with \1 where the phrase is to be inserted (defaults to 
    # '<strong class="highlight">\1</strong>') 
    # 
    # ==== Examples 
    # highlight('You searched for: rails', 'rails') 
    # # => You searched for: <strong class="highlight">rails</strong> 
    # 
    # highlight('You searched for: ruby, rails, dhh', 'actionpack') 
    # # => You searched for: ruby, rails, dhh 
    # 
    # highlight('You searched for: rails', ['for', 'rails'], :highlighter => '<em>\1</em>') 
    # # => You searched <em>for</em>: <em>rails</em> 
    # 
    # highlight('You searched for: rails', 'rails', :highlighter => '<a href="search?q=\1">\1</a>') 
    # # => You searched for: <a href="search?q=rails">rails</a> 
    # 
    # highlight('Šumné dievčatá', ['šumňe', 'dievca'], :ignore_special_chars => true) 
    # # => <strong class="highlight">Šumné</strong> <strong class="highlight">dievča</strong>tá 
    # 
    # You can still use <tt>highlight</tt> with the old API that accepts the 
    # +highlighter+ as its optional third parameter: 
    # highlight('You searched for: rails', 'rails', '<a href="search?q=\1">\1</a>')  # => You searched for: <a href="search?q=rails">rails</a> 
    def highlight(text, phrases, *args) 
    options = args.extract_options! 
    unless args.empty? 
     options[:highlighter] = args[0] || '<strong class="highlight">\1</strong>' 
    end 
    options.reverse_merge!(:highlighter => '<strong class="highlight">\1</strong>') 

    if text.blank? || phrases.blank? 
     text 
    else 
     haystack = text.clone 
     match = Array(phrases).map { |p| Regexp.escape(p) }.join('|') 
     if options[:ignore_special_chars] 
     haystack = haystack.mb_chars.normalize(:kd) 
     match = match.mb_chars.normalize(:kd).gsub(/[^\x00-\x7F]+/n, '').gsub(/\w/, '\0[^\x00-\x7F]*') 
     end 
     highlighted = haystack.gsub(/(#{match})(?!(?:[^<]*?)(?:["'])[^<>]*>)/i, options[:highlighter]) 
     highlighted = highlighted.mb_chars.normalize(:kc) if options[:ignore_special_chars] 
     highlighted 
    end 
    end 
0

這聽起來像你正在使用決定比賽是否已經發生與否兩種不同的方法:一個是搜索,一個用於高亮。使用與搜索突出顯示相同的方法,它應該選擇它,不是?

+0

actualy我正在使用查找條件來查找記錄,並突出顯示它。所以,只建立在函數中,一個用於DB邏輯,另一個用於可視邏輯。 – 2008-09-27 03:45:24

3

也許您正在直接針對MySQL數據庫搜索UTF-8字符串?

正確配置的MySQL服務器(以及可能的任何其他主流數據庫服務器)將正確執行,不區分大小寫和不區分重音的比較。不過,這不是Ruby的情況。從版本1.8開始,Ruby不支持Unicode字符串。因此,您從數據庫服務器獲得了正確的結果,但Rails的突出顯示函數使用gsub未能找到您的搜索字符串。您需要使用支持Unicode的字符串庫(如ICU4R)重新實現突出顯示

1

這裏是我的article解釋了優雅的解決方案,你並不需要導軌或的ActiveSupport。