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