我必须使用长文本并在其中使用regexp进行替换。 现在我写了下面的代码:
text = File.read(file)
replacements = [
[/```([\w]+)/, "\n\1>"],
[/```\n/, "\n\n"],
[/pattern not found/, 'sub'],
[/pattern that should be found/, 'no sub'],
]
replacements.inject(text) do |text, (k,v)|
if text =~ k
text.gsub!(k,v)
end
end
File.write(name', text)
如果在我的文档中找到每个正则表达式,一切正常,但如果找不到替换模式,则不会执行所有后续替换。
我放了if text =~ k
,但它不起作用。
有什么想法吗?
答案 0 :(得分:3)
原因是如果没有替换,String#gsub!
会返回nil
,如果有替换,则返回结果。另一个小问题是你调用匹配两次,text =~ k
的检查是多余的。
我会选择{em> not inplace 版本的gsub
:
result = replacements.inject(text) do |text, (k, v)|
text.gsub(k, v)
end
以上应该可以解决问题。
您是否仍想使用就地替换,您可能只会在失败的text
上返回gsub!
:
result = replacements.inject(text) do |text, (k, v)|
text.gsub!(k, v) || text
end
答案 1 :(得分:2)
inject
的块必须返回memo
值。因此,您可能需要更改代码才能执行此操作:
replacements.inject(text) do |text, (k,v)|
text.gsub(k,v)
end
如果if test =~ k
在您的情况下失败,则该块的输出为nil
- 因此,问题就出现了。
或者,您可以使用with_object
replacements.each.with_object(text) do |(k,v), text|
text.gsub!(k,v)
end
答案 2 :(得分:2)
每次注入迭代都应该将备忘录(在您的情况下为text
)返回到下一次迭代。试试这段代码:
replacements.inject(text) do |text, (k,v)|
if text =~ k
text.gsub!(k,v)
end
text
end