我该怎么办?我尝试过这个gsub,但是如果strings_to_highlight数组很大,我无法弄清楚它真正有效。干杯!
string = "Roses are red, violets are blue"
strings_to_highlight = ['red', 'blue']
# ALGORITHM HERE
resulting_string = "Roses are (red), violets are (blue)"
答案 0 :(得分:5)
Regexp
有一个有用的union
函数,用于将正则表达式组合在一起。坚持使用正则表达式,直到遇到性能问题:
string = "Roses are red, violets are blue"
strings_to_highlight = ['red', 'blue']
def highlight(str, words)
matcher = Regexp.union words.map { |w| /\b(#{Regexp.escape(w)})\b/ }
str.gsub(matcher) { |word| "(#{word})" }
end
puts highlight(string, strings_to_highlight)
答案 1 :(得分:4)
strings_to_highlight = ['red', 'blue']
string = "Roses are red, violets are blue"
strings_to_highlight.each { |i| string.gsub!(/\b#{i}\b/, "(#{i})")}
答案 2 :(得分:2)
我建议使用String#gsub的形式,使用哈希进行替换。
strings_to_highlight = ['red', 'blue']
首先构造哈希。
h = strings_to_highlight.each_with_object({}) do |s,h|
h[s] = "(#{s})"
ss = "#{s[0].swapcase}#{s[1..-1]}"
h[ss] = "(#{ss})"
end
#=> {"red"=>"(red)", "Red"=>"(Red)", "Blue"=>"(Blue)", "blue"=>"(blue)"}
接下来为它定义一个默认的proc:
h.default_proc = ->(h,k) { k }
因此如果h
没有密钥k
,h[k]
会返回k
(例如h["cat"] #=> "cat"
)。
准备好了!
string = "Roses are Red, violets are blue"
string.gsub(/[[[:alpha:]]]+/, h)
=> "Roses are (Red), violets are (blue)"
这应该是相对有效的,因为只需要通过字符串一次并且哈希查找非常快。
答案 3 :(得分:1)
我会用:
string = "Roses are red, violets are blue"
strings_to_highlight = ['red', 'blue']
string.gsub(/\b(#{Regexp.union(strings_to_highlight).source})\b/) { |s| "(#{s})" } # => "Roses are (red), violets are (blue)"
以下是它如何分解:
/\b(#{Regexp.union(strings_to_highlight).source})\b/ # => /\b(red|blue)\b/
嵌入模式时使用source
非常重要。没有它会导致:
/\b(#{Regexp.union(strings_to_highlight)})\b/ # => /\b((?-mix:red|blue))\b/
如果您不理解regex-ese中的含义,(?-mix:...)
部分可能会导致问题。 Regexp文档解释了这些标志,但是如果你不知道这个问题,那么如果没有这样做就会导致很难诊断错误。
\b
告诉引擎匹配单词,而不是子串。没有它,你最终可能会:
string = "Fred, bluette"
strings_to_highlight = ['red', 'blue']
string.gsub(/(#{Regexp.union(strings_to_highlight).source})/) { |s| "(#{s})" }
# => "F(red), (blue)tte"
使用gsub
的块允许我们对匹配的值执行计算。