HiveBrain v1.2.0
Get Started
← Back to all entries
patternrubyrailsMinor

Refactor highlight matched word in string

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
matchedwordrefactorstringhighlight

Problem

I have following method which highlight matched word in text:

# Hightlight matched term
#
# Ex(for term: some):
#   "Some CEO Event"
#
def highlight_matched(matched_word, text)
  regex = matched_word.gsub(/\*|\"|\'/, "")
                       .split(" ")
                       .map { |s| "\\b#{s}" }.join('|')

  text.gsub(/(#{regex})/i, '\1')
end


Is there a better solution for that?

I am using it here:

"%s %s" %[highlight_matched(title[0..70]), content_tag(:span, caption, class: 'search-type')]

Solution

If text may contain HTML (in that case text is a somewhat misleading variable name) you definitely should use a HTML parser. What about this? (adding a
as wrapper, otherwise xpath won't find parent text nodes).

require 'nokogiri'

def highlight(html, word)
  Nokogiri::HTML::fragment("" + html + "").tap do |doc|
    doc.search('.//text()').each do |text_node|
      new_contents = text_node.text.gsub(/\b(#{word})\b/i, '\1')
      text_node.replace(new_contents)
    end
  end.xpath("p").inner_html
end

puts highlight('Run Rabbit Run', "run")
# Run     
# Rabbit Run

Code Snippets

require 'nokogiri'

def highlight(html, word)
  Nokogiri::HTML::fragment("<p>" + html + "</p>").tap do |doc|
    doc.search('.//text()').each do |text_node|
      new_contents = text_node.text.gsub(/\b(#{word})\b/i, '<span class="bold">\1</span>')
      text_node.replace(new_contents)
    end
  end.xpath("p").inner_html
end

puts highlight('<p><a href="http://runner.com">Run Rabbit Run</a></p>', "run")
# <p><a href="http://runner.com"><span class="bold">Run</span>     
# Rabbit <span class="bold">Run</span></a></p>

Context

StackExchange Code Review Q#19744, answer score: 4

Revisions (0)

No revisions yet.