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