我不太清楚我是否理解非捕获组的工作原理。我正在寻找一个正则表达式来产生这个结果:5.214
。我认为下面的正则表达式可行,但它正在取代包括非捕获组在内的所有内容。如何编写正则表达式才能替换捕获组?
"5,214".gsub(/(?:\d)(,)(?:\d)/, '.')
# => ".14"
我想要的结果:
"5,214".gsub(some_regex)
#=> "5.214
答案 0 :(得分:19)
你不能。 gsub
取代整场比赛;它对捕获的组没有任何作用。无论这些群体是否被捕获都没有任何区别。
为了达到效果,你需要使用lookbehind和lookahead。
"5,214".gsub(/(?<=\d),(?=\d)/, '.')
答案 1 :(得分:9)
非捕获组仍然消耗比赛
使用
"5,214".gsub(/(\d+)(,)(\d+)/, '\1.\3')
或
"5,214".gsub(/(?<=\d+)(,)(?=\d+)/, '.')
答案 2 :(得分:8)
gsub
替换正则表达式引擎生成的整个匹配项。
RTFM,不保留捕获/非捕获组构造。但是,您可以使用lookaround断言,这些断言不会消耗&#34;字符串上的任何字符。
"5,214".gsub(/\d\K,(?=\d)/, '.')
说明: \K
转义序列重置报告的匹配的起点,不再包含任何以前消费的字符。话虽如此,我们然后查找并匹配逗号,而Positive Lookahead断言数字跟随。
答案 3 :(得分:4)
也可以在块版本中使用Regexp.last_match
(也可以通过$~
使用)来访问完整的MatchData
:
"5,214".gsub(/(\d),(\d)/) { |_|
match = Regexp.last_match
"#{match[1]}.#{match[2]}"
}
这可以更好地扩展到涉及更多的用例。
Nota bene,来自Ruby文档:
:: last_match在进行模式匹配的方法的线程和方法范围内是本地的。
答案 4 :(得分:0)
我对红宝石一无所知。
但是我在tutorial
中看到的 gsub意味着替换,
模式应为/(?<=\d+),(?=\d+)/
,只需用逗号替换逗号即可
或者,使用捕获/(\d+),(\d+)/
将字符串替换为"\1.\2"
?
答案 5 :(得分:0)
您不需要正则表达式来实现您的需求:
'1,200.00'.tr('.','!').tr(',','.').tr('!', ',')
1,200!00
)1.200!00
)1.200,00
)