繁体   English   中英

替换 Ruby 中所有与 RegExp 模式不匹配的单词

[英]Replace all words which don't match a RegExp pattern in Ruby

我在 ruby 中有一个字符串,比方说
"hello, I am a string, I am surrounded by quotes"
我想替换所有与 RegExp 模式不匹配的单词(以空格分隔),假设/.+?s/"foo" 所以结果是
"foo foo foo foo string, foo foo surrounded foo quotes"

因为单词有分隔符我可以做

str = "hello, I am a string, I am surrounded by quotes"
str = str.split
str.each{
  |e|
  x = e.match(/(.+)?s/)
  if x.to_s.empty? then e.replace "foo" end
}
str = str.join(" ")
puts str # -> foo foo foo foo string, foo foo surrounded foo quotes

但是有更好的方法吗? 因为对于一个相对简单的操作来说,这是相当多的代码。

替换任何不以s开头或结尾的单词

假设您的真正规则是排除以字符s开头或结尾的单词,您可以拆分单词,然后将 map String#gsub拆分到每个元素上。 例如,使用 Ruby 2.7.2+(我实际上使用的是 3.0.0-preview1):

str = "hello, i am a string, i am surrounded by quotes"
str.split.map { _1.gsub(/\b[^s]+\b/) { "foo" } }.join ?\s
#=> "foo, foo foo foo string, foo foo surrounded foo quotes"

这也适用于早期的 Ruby 版本。 只需将位置块参数(例如_1 )替换为word之类的命名变量,并且(如果您愿意)将简写?\s替换为"\s" 例如,使用 Ruby 2.5.8:

str = 'hello, i am a string, i am surrounded by quotes'
str.split.map do |word|
  word.gsub(/\b[^s]+\b/) { 'foo' }
end.join "\s"
#=> "foo, foo foo foo string, foo foo surrounded foo quotes"

结果应该是相同的两种方式。

我说的是红宝石弦
"hello, I am a string, I am surrounded by quotes"
并且我想用/.+?s/模式替换所有不匹配RegExp模式的单词(用空格隔开),让/.+?s//.+?s/ "foo" 所以结果是
"foo foo foo foo string, foo foo surrounded foo quotes"

因为单词有分隔符,我可以做

str = "hello, I am a string, I am surrounded by quotes"
str = str.split
str.each{
  |e|
  x = e.match(/(.+)?s/)
  if x.to_s.empty? then e.replace "foo" end
}
str = str.join(" ")
puts str # -> foo foo foo foo string, foo foo surrounded foo quotes

但是有更好的方法吗? 因为对于一个相对简单的操作来说,这是很多代码。

从您的示例来看,您似乎想用'foo'替换所有单词,但包含's'单词除外; 'string''surrounded''quotes' 为此,您可以将/(.+)?s/简化为/s/ (例如, 'beeswax'.match?(/s/) #=> true )。

最好在整个字符串上使用String#gsub ,因为它会保留单词之间的额外空格。 如果改为在空格上拆分字符串,替换结果数组中的每个单词,然后join这些元素以形成一个新字符串,则多余的空格将被删除。 例如,如果一个人是老式的,在句子之间插入两个空格,我们可能有以下内容。

str = "Hello, I use a string of words, surrounded by quotes.  So there."
                                                             

并希望在结果字符串中保留句点后的两个空格。 此外,拆分空格然后连接修改后的单词会创建一个不必要的数组。

假设我们希望用'foo'替换包含匹配's''S'的单词。 包含's''S'的单词匹配正则表达式

r = /s/i

然后我们可以写:

str.gsub(/\w+/) { |s| s.match?(r) ? s : 'foo' }
  #=> "foo, foo use foo string foo words, surrounded foo quotes.  So foo."

gsub的参数是匹配单词的正则表达式。

考虑第二个例子。 假设我们将所有既不以's''S'开头也不以 'foo' 结尾的单词替换为'foo' 也就是说,不匹配正则表达式的单词

r = /\As|s\z/i

我们可以用同样的方式做到这一点:

str.gsub(/\w+/) { |s| s.match?(r) ? s : 'foo' }
  #=> "foo, foo foo foo string foo words, surrounded foo quotes.  So foo."

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM