Ruby Regex取代了最后的分组存在

时间:2015-05-14 12:43:18

标签: ruby regex match gsub

在Ruby正则表达式中,我想使用gsub替换最后一次出现的分组(如果发生),否则,无论如何都要在默认位置执行替换。我试图替换40年代(40 ... 49)中最后一次出现的数字。我有以下正则表达式,它正确地捕获了'\3'中我想要的分组:

/(([1-3,5-9][0-9]|([4][0-9]))[a-z])*Foo/

我正在使用此正则表达式的一些示例字符串是:

12a23b34c45d56eFoo
12a45b34c46d89eFoo
45aFoo
Foo
12a23bFoo
12a23b445cFoo

使用https://regex101.com/,我看到'\3'中捕获了40s中的最后一个数字。然后,我想以某种方式执行string.gsub(regex, '\3' => 'NEW')来替换最后一次出现,或者如果不存在则在Foo之前​​追加。我期望的结果将是:

12a23b34cNEWd56eFoo
12a45b34cNEWd89eFoo
NEWaFoo
NEWFoo
12a23bNEWFoo
12a23b4NEWcFoo

2 个答案:

答案 0 :(得分:1)

如果我理解正确,您对gsub codeblock感兴趣:

str.gsub(PATTERN) { |mtch|
  puts mtch                # the whole match
  puts $~[3]               # the third group
  mtch.gsub($~[3], 'NEW')  # the result
}

'abc'.gsub(/(b)(c)/) { |m| m.gsub($~[2], 'd') }
#⇒ "abd"

当根本没有40 - s出现时,你应该处理这种情况,例如:

gsub($~[1], "NEW$~[1]") if $~[3].nil?

要处理所有可能的情况,可以声明Foo的组:

#                           NOTE THE GROUP ⇓⇓⇓⇓⇓
▶ re = /(([1-3,5-9][0-9]|([4][0-9]))[a-z])*(Foo)/
#⇒ /(([1-3,5-9][0-9]|([4][0-9]))[a-z])*(Foo)/
▶ inp.gsub(re) do |mtch|
▷   $~[3].nil? ? mtch.gsub($~[4], "NEW#{$~[4]}") : mtch.gsub(/#{$~[3]}/, 'NEW')  
▷ end
#⇒ "12a23b34cNEWd56eFoo\n12a45b34cNEWd89eFoo\nNEWaFoo\nNEWFoo\n12a23bNEWFoo"

希望它有所帮助。

答案 1 :(得分:0)

我建议如下:

'12a23b34c45d56eFoo'.gsub(/(([1-3,5-9][0-9]|([4][0-9]))[a-z])*Foo/) {
  if Regexp.last_match[3].nil? then
    puts "Append before Foo"
  else 
    puts "Replace group 3"
  end 
}

你需要找到一种方法来相应地追加或替换,或者有人可以使用简洁的代码进行编辑......