У меня есть микро-мини-поисковая система, которая выделяет поисковые запросы в моем приложении rails. При поиске акценты игнорируются, а при выделении регистр не учитывается. Практически идеально. Но, например, если у меня есть запись с текстом «pão de queijo» и я ищу «pao de queijo», возвращается запись является, но выделен iext не является. Точно так же, если я ищу "pÃo de queijo", запись возвращается, но не выделяется должным образом.
Мой код очень прост:
<%= highlight(result_pessoa.observacoes, search_string, '<span style = "background-color: yellow;"></span>') %>





похоже, что вы используете два разных метода для определения совпадения или нет: один для вашего поиска, а другой для высот. Используйте тот же метод, что и при поиске, для выделения, и он должен его уловить, не так ли?
Может быть, вы ищете строки UTF-8 непосредственно в базе данных MySQL?
Правильно сконфигурированный сервер MySQL (и, вероятно, любой другой основной сервер баз данных) будет правильно работать при сравнении без учета регистра и без учета акцента.
Однако это не относится к Ruby. Начиная с версии 1.8 Ruby не поддерживает строки Unicode. Итак, вы получаете правильные результаты от вашего сервера базы данных, но функция выделять Rails, которая использует gsub, не может найти вашу строку поиска. Вам необходимо повторно реализовать выделять, используя библиотеку строк с поддержкой Unicode, например ICU4R.
Я только что отправил патч для 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
Вот мой статья, который объясняет элегантное решение, в котором вам не нужны Rails или ActiveSupport.
на самом деле я использую find с условиями, чтобы найти запись, и выделите, чтобы выделить ее. Итак, только встроенные функции, одна для логики БД, а другая для визуальной логики.