假设:
check_for = ["Lorem", "ipsum", "dolor", "sit", "amet"]
replace_with = ["Donec", "ut", "libero", "sed", "arcu"]
sentence = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec a diam lectus. Sed sit amet ipsum mauris. Maecenas congue ligula ac quam viverra nec consectetur ante hendrerit. Donec et mollis dolor. Praesent et diam eget libero egestas mattis sit amet vitae augue. Nam tincidunt congue enim, ut porta lorem lacinia consectetur."
如果它包含放在数组'check_for'中的单词并且如果找到它们,请如何检查'句子'中的整个字符串,替换为'replace_with'中的单词?
check_for中的单词可以替换为replace_with中具有相同索引的单词:
check_for [idx]应替换为replace_with [idx]
我使用嵌套循环使用Javascript做了类似的事情。出于某种原因,这不适用于Ruby。
我对嵌套循环的想法是将句子分成数组并使用带有i和j的while循环。因此,句子[i]将从0开始:
sentence[i] == check_for[j]
然后:
sentence[i] = replace_with[j]
除了这个想法不起作用之外,我确信在Ruby中还有一种更直接的方式。
不区分大小写即可。
答案 0 :(得分:7)
可以使用定义替换的哈希来完成:
sentence = "Lorem ipsum dolor sit amet, consectetur adipiscing elit..."
replacements = {
'Lorem' => 'Donec',
'ipsum' => 'ut',
'dolor' => 'libero',
'sit' => 'sed',
'amet' => 'arcu',
}
sentence.gsub(Regexp.union(replacements.keys), replacements)
#=> "Donec ut libero sed arcu, consectetur adipiscing elit..."
顺便说一下,您可以轻松地从数组中生成replacements
哈希:
replacements = Hash[check_for.zip(replace_with)]
Cary Swoveland建议使用简化的Regexp:
sentence.gsub(/\w+/, replacements)
我真的很喜欢,因为它读得更好。
我想知道rexexp是否会对性能产生影响:一方面构建一个复杂但专门的正则表达式。另一方面,使用简单的正则表达式,但必须检查每个单词与哈希。
require 'benchmark'
def simple
@sentence.gsub(/\w+/, @replacements)
end
def union
@sentence.gsub(Regexp.union(@replacements.keys), @replacements)
end
n = 100_000
Benchmark.bmbm(15) do |x|
x.report("simple :") { n.times do; simple; end }
x.report("union :") { n.times do; union ; end }
end
# Rehearsal ---------------------------------------------------
# simple : 4.790000 0.010000 4.800000 ( 4.804576)
# union : 3.820000 0.020000 3.840000 ( 3.846012)
# ------------------------------------------ total: 8.640000sec
事实证明,较长的版本更快一点。但我很确定这可能会根据sentence
的长度和要替换的元素数量而改变。
答案 1 :(得分:1)
replaced_sentence = []
sentence.split.each do |word|
if idx = check_for.index(word.match(/\w+/).to_s)
replaced_sentence << word.gsub((/\w+/) , replace_with[idx] )
else
replaced_sentence << word
end
end
replaced_sentence.join(' ')
#=> "Donec ut libero sed amet, consectetur adipiscing elit..."
这会遍历句子的每个单词。如果check_for
包含单词(减去标点符号),check_for.index(word...)
将返回该索引值。然后将该索引值分配给idx
,replace_with[idx]
的值替换该单词,并且&#34;推送&#34;到新的replaced_sentence
数组。
如果该字词不匹配,check_for.index(word)
会返回nil
,这会导致if
语句不成立,原始word
获得推到新阵列。