我有一个微型迷你搜索引擎,可以在我的rails应用中突出显示搜索字词。搜索忽略重音,突出显示不区分大小写。几乎完美。 但是,例如,如果我有一个带有“pãodequeijo”文本并且搜索“pao de queijo”的记录,则返回记录 但突出显示iext 。同样,如果我搜索“pÃodede queijo”,则会返回记录,但不会正确突出显示。
我的代码很简单:
<%= highlight(result_pessoa.observacoes, search_string, '<span style="background-color: yellow;">\1</span>') %>
答案 0 :(得分:3)
也许您正在直接针对MySQL数据库搜索UTF-8字符串?
正确配置的MySQL服务器(可能还有任何其他主流数据库服务器)将通过不区分大小写和不区分重音的比较正确执行。
但不是Ruby的情况。从版本1.8开始,Ruby不支持Unicode字符串。因此,您从数据库服务器获得了正确的结果,但使用 gsub 的Rails的突出显示功能无法找到您的搜索字符串。您需要使用支持Unicode的字符串库重新实现突出显示,例如ICU4R。
答案 1 :(得分:3)
我刚刚向Rails提交了补丁,解决了这个问题。
# 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
答案 2 :(得分:1)
这是我的article,它解释了您不需要Rails或ActiveSupport的优雅解决方案。
答案 3 :(得分:0)