@wordsToHighlight=["important","monkey","dancing"]
def highlightText(input)
for i in 0..@wordsToHighlight.length-1 do
input = input.gsub(@wordsToHighlight[i],"*" + @wordsToHighlight[i] + "*")
end
return input
end
Refactorings
No refactoring yet !
macournoyer
January 3, 2008, January 03, 2008 14:26, permalink
Here's my take, it's short but not perfect
def highlight_text(input, words_to_highlight=%w(important monkey dancing))
input.gsub(/#{words_to_highlight.join('|')}/i, '*\0*')
end
puts highlight_text("Hey monkey, it's important you start dancing right now!")
# >> Hey *monkey*, it's *important* you start *dancing* right now!
mvanholstyn
January 3, 2008, January 03, 2008 14:33, permalink
def highlight_text(input, words_to_highlight = [], wrapper = '*\1*')
input.gsub(/\b(#{words_to_highlight.join("|")})\b/, wrapper)
end
Jason
January 3, 2008, January 03, 2008 14:34, permalink
this dumbass ajax form is not working!
def highlightText(input, open_tag, close_tag)
input.split(/ /).collect {|word| @wordsToHighlight.include?(word) ? "#{open_tag}#{word}#{close_tag}" : word }.join(" ")
end
input = "The world of very important things contained many monkeys that really liked dancing around!"
p highlightText(input, "<b>", "</b>")
Jason
January 3, 2008, January 03, 2008 14:38, permalink
Revision 2, this time passing in list of words to highlight as a function argument like macournoyer did (first reply), which is much better than accessing a named variable outside of the function.
def highlightText(input, open_tag, close_tag, words_to_highlight)
input.split(/ /).collect {|word| words_to_highlight.include?(word) ? "#{open_tag}#{word}#{close_tag}" : word }.join(" ")
end
list_of_words=["important","monkey","dancing"]
input = "The world of very important things contained many monkeys that really liked dancing around!"
p highlightText(input, "<b>", "</b>", list_of_words)
macournoyer
January 3, 2008, January 03, 2008 14:41, permalink
Sorry about the form not working Jason, should be fixed now
Justin Jones
January 3, 2008, January 03, 2008 15:15, permalink
Good solutions above. This is overkill, but can't think of anything else that hasn't already been done.
class String
def hilight(marker = '*', *args)
gsub(/\b(#{args.join('|')})\b/, "#{marker}\\1#{marker}")
end
end
words = %w(monkeys dancing important)
input = "The world of very important things contained many monkeys that really liked dancing around!"
input.hilight('*', *words)
Jason Dew
January 3, 2008, January 03, 2008 17:24, permalink
i purposely wrote this without looking at the refactorings... funny how close it still is but it's a bit different. a little more verbose imo but extensible. the only issue i have with it is that you are limited to one a single delimiter.
class Highlighter
def initialize(keywords, prefix='*', suffix='*', delimiter=' ')
@keywords, @prefix, @suffix, @delimiter = keywords, prefix, suffix, delimiter
end
def highlight(text)
text.split(@delimiter).collect do |word|
@keywords.include?(word) ? highlight_word(word) : word
end.join(@delimiter)
end
private
def highlight_word(word)
@prefix + word + @suffix
end
end
highlighter = Highlighter.new %w(important monkey dancing)
text = "there are some very important monkeys dancing the most important of all dances in monkey land"
highlighted_text = highlighter.highlight(text)
puts "ORIGINAL : #{text}"
puts "HIGHLIGHTED: #{highlighted_text}"
Justin Jones
January 3, 2008, January 03, 2008 20:05, permalink
I'm sure the String#pad (not sure about the name either) utility function added here is available somewhere, but anyways. Also using the block version of gsub this time.
class String
def pad(char = ' ')
"#{char}#{self}#{char}"
end
def highlight(marker = '*', *args)
gsub(/\b(#{args.join('|')})\b/) { |word| word.pad(marker) }
end
end
words = %w(monkeys dancing important)
input = "The world of very important things contained many monkeys that really liked dancing around!"
input.highlight('*', *words)
Jens Ruzicka
January 6, 2008, January 06, 2008 14:27, permalink
There are already better versions here
def highlight_text words_to_highlight, fore="*", after="*"
self.split.each do |token|
if words_to_highlight =~ token
STDOUT << "#{fore} #{$&} #{after} "
else
STDOUT << "#{token} "
end
end
end
line = "This is an important text about a dancing monkey"
line.highlight_text %r{important|dancing|monkey}, "<b>", "</b>"
gets
David Madden
January 7, 2008, January 07, 2008 13:51, permalink
Nothing major here, just made it case insensitive. An issue I have is that hyphenated words like "monkey-wrench" will still get highlighted and I have no idea how to get the regexp to ignore words beginning or ending with a -.
def highlight_text(input, words=%w(important monkey dancing), sym='*')
input.gsub(/\b(#{words.join("|")})\b/i, "#{sym}\\1#{sym}")
end
puts highlight_text("This is the Important text to highlight. Can you see the dancing monkey-wrench?")
Mike
January 9, 2008, January 09, 2008 04:55, permalink
Probably went overboard.
class String
def highlight(mark='*')
mark+self+mark
end
end
class Sentence
attr_writer :words_to_highlight
def initialize(string='')
@string = string
@words_to_highlight = %w()
end
def highlight(words_to_highlight=@words_to_highlight,mark='*')
all_words = @string.split(/\b/)
highlighted = all_words.collect do |word|
( words_to_highlight.include?(word) ) ? word.highlight : word
end
highlighted.join()
end
def to_s
@string
end
end
sentence = Sentence.new("hello world, whats happening?")
puts sentence
puts sentence.highlight(%w(world whats))
sentence.words_to_highlight = %w(world)
puts sentence.highlight
Mike
January 9, 2008, January 09, 2008 05:07, permalink
another one, neither of these work on contractions, this one features recursion and only involves modifying string.
This one outputs:
*hello* world, what's *up*?
class String
def highlight(words=%w(), mark='*')
if ( self.split(/\b/).length == 1 )
words.include?(self) ? mark+self+mark : self
else
self.split(/\b/).collect { |w| w.highlight(words) }.join
end
end
end
puts "hello world, what's up?".highlight(%w(hello up))
Mike
January 9, 2008, January 09, 2008 05:11, permalink
found a bug in that one, didnt work when you had a full sentence and passed in a mark.
This one will correctly output +hello+ world, what's +up+?
I'm going to stop now, sorry for the triple post.
class String
def highlight(words=%w(), mark='*')
if ( self.split(/\b/).length == 1 )
words.include?(self) ? mark+self+mark : self
else
self.split(/\b/).collect { |w| w.highlight(words, mark) }.join
end
end
end
puts "hello world, what's up?".highlight(%w(hello up), '+')
Simon Gate
January 9, 2008, January 09, 2008 23:43, permalink
How i did it.
class String
def highlight(words = nil, mark = "*")
words.nil? ? self : self.gsub(/#{words.join("|")}/) {|s| "#{mark}#{s}#{mark}"}
end
end
puts "A very important list is in monkey dancing tonight with pants down in rain today.".highlight %w(monkey dancing today)
Sean Cribbs
January 26, 2008, January 26, 2008 18:11, permalink
Regexp.union is your friend! This also demonstrates a typical use of the splat operator to turn an array into an argument list, and the usage of back-references in global substitutions. One thing that I found recently is that your replacement string needs to be in single-quotes or Ruby will turn your \0,\1, etc references into the corresponding ASCII characters instead of the backreferences! If you use a double-quoted string, \\0, \\1 etc. should accomplish the same thing.
@wordsToHighlight=["important","monkey","dancing"]
def highlightText(input)
input.gsub(Regexp.union(*@wordsToHighlight), '*\0*')
end
puts highlightText("I think it's important to have a dancing monkey in your bedroom.")
# => I think it's *important* to have a *dancing* *monkey* in your bedroom.
Sean Cribbs
January 26, 2008, January 26, 2008 18:16, permalink
Now having read some of the others, I'll borrow from Simon's idea:
class String
def highlight(words=[])
words.empty? ? self : self.gsub(Regexp.union(*words), '*\0*')
end
end
puts "I think it's important to have a dancing monkey in your bedroom.".highlight %w(important monkey dancing)
# => I think it's *important* to have a *dancing* *monkey* in your bedroom.
Here is the 5th edition of Rubyize this. You can find the original blog post on ruby fleebie here : http://www.rubyfleebie.com/rubyize-this-5th-edition/
Tom wrote a very simple ruby script to highlight some words in a text. He chose to highlight the words with asterisks, like *that* (In 2 months, perhaps Tom will have to use his script to produce HTML output or something else... he will be screwed with those basic asterisks). Tom has absolutely no ruby background, help him refactor his code <em>ala</em> Ruby, that is : short, clean and simple.
By the way, Tom didn't put a lot of effort in his algorithm. His dumb gsub thing will mistakenly replace <em>parts of words</em> instead of whole words only. Maybe some improvements would be needed there.