Ruby - 数组检查并替换为
Ruby - arrays check for and replace with
鉴于:
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."
如何检查 'sentence' 中的整个字符串,如果它包含数组 'check_for' 中的单词,如果找到,则替换为 'replace_with' 中的单词?
check_for中的词可以用replace_with中具有相同索引的词替换:
check_for[idx] 应替换为 replace_with[idx]
我已经用 Javascript 使用嵌套循环完成了一些 "similar"。由于某种原因,这不适用于 Ruby.
我对嵌套循环的想法是将句子拆分为数组,并使用 i 和 j 的 while 循环。所以 sentence[i] 将从 0:
开始
sentence[i] == check_for[j]
然后:
sentence[i] = replace_with[j]
除了这个想法行不通之外,我确信 Ruby 中有更直接的方法。
不区分大小写即可。
这可以通过定义替换的散列来完成:
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 建议使用简化的正则表达式:
sentence.gsub(/\w+/, replacements)
我真的很喜欢,因为它读起来更漂亮。
我想知道 rexexp 是否对性能有影响:一方面构建复杂但专门的 regexp。另一方面使用简单的正则表达式,但必须根据哈希检查每个单词。
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
的长度和要替换的元素数量而改变。
这是一种无需替换哈希的方法,使用 #index
method:
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...)
returns 即索引值。然后将该索引值分配给 idx
,replace_with[idx]
的值替换单词并 "pushed" 到新的 replaced_sentence
数组。
如果没有匹配词 check_for.index(word)
returns nil
,这会导致 if
语句不成立,而原始 word
被推送到新数组。
鉴于:
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."
如何检查 'sentence' 中的整个字符串,如果它包含数组 'check_for' 中的单词,如果找到,则替换为 'replace_with' 中的单词?
check_for中的词可以用replace_with中具有相同索引的词替换:
check_for[idx] 应替换为 replace_with[idx]
我已经用 Javascript 使用嵌套循环完成了一些 "similar"。由于某种原因,这不适用于 Ruby.
我对嵌套循环的想法是将句子拆分为数组,并使用 i 和 j 的 while 循环。所以 sentence[i] 将从 0:
开始sentence[i] == check_for[j]
然后:
sentence[i] = replace_with[j]
除了这个想法行不通之外,我确信 Ruby 中有更直接的方法。
不区分大小写即可。
这可以通过定义替换的散列来完成:
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 建议使用简化的正则表达式:
sentence.gsub(/\w+/, replacements)
我真的很喜欢,因为它读起来更漂亮。
我想知道 rexexp 是否对性能有影响:一方面构建复杂但专门的 regexp。另一方面使用简单的正则表达式,但必须根据哈希检查每个单词。
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
的长度和要替换的元素数量而改变。
这是一种无需替换哈希的方法,使用 #index
method:
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...)
returns 即索引值。然后将该索引值分配给 idx
,replace_with[idx]
的值替换单词并 "pushed" 到新的 replaced_sentence
数组。
如果没有匹配词 check_for.index(word)
returns nil
,这会导致 if
语句不成立,而原始 word
被推送到新数组。