Ruby正则表达式 - gsub只捕获组

dia*_*ks2 20 ruby regex

我不太清楚我是否理解非捕获组的工作原理.我正在寻找一个正则表达式来产生这个结果:5.214.我认为下面的正则表达式可行,但它正在取代包括非捕获组在内的所有内容.如何编写正则表达式才能替换捕获组?

"5,214".gsub(/(?:\d)(,)(?:\d)/, '.')
# => ".14"
Run Code Online (Sandbox Code Playgroud)

我想要的结果:

"5,214".gsub(some_regex)
#=> "5.214
Run Code Online (Sandbox Code Playgroud)

saw*_*awa 22

你不能.gsub取代整场比赛; 它对捕获的组没有任何作用.无论是否捕获这些组,都没有任何区别.

为了达到结果,您需要使用lookbehind和lookahead.

"5,214".gsub(/(?<=\d),(?=\d)/, '.')
Run Code Online (Sandbox Code Playgroud)

  • 我个人发现[alpha bravo的回答](/sf/users/190175471/).对于非平凡的正则表达式,IMO更容易实现.`"5,214".gsub(/(\ d +)(,)(\ d +)/,'\ 1.\3')`.它的作用是:定义三组:(之前)(你需要替换的)(之后),现在替换为(之前)(替换)(之后). (4认同)

alp*_*avo 15

非捕获组仍然消耗匹配
使用
"5,214".gsub(/(\d+)(,)(\d+)/, '\1.\3')

"5,214".gsub(/(?<=\d+)(,)(?=\d+)/, '.')

  • "5,214".gsub(/(\ d +),(\ d +)/,'\ 1.\2')也有效.并保存一个不需要的捕获组. (2认同)

hwn*_*wnd 7

\K 替换正则表达式引擎生成的整个匹配项.

RTFM,捕获/非捕获组构造都不会保留.但是,您可以使用不会"消耗"字符串上任何字符的外观断言.

"5,214".gsub(/\d\K,(?=\d)/, '.')
Run Code Online (Sandbox Code Playgroud)

说明:\K转义序列重置报道比赛的出发点和任何先前消耗字符不再列入.话虽如此,我们然后寻找并匹配逗号,而正向前瞻断言,数字跟随.

  • 您的个人资料中列出的[Explain Regular Expressions工具](http://liveforfaith.com/re/explain.pl)非常有用且很酷.谢谢你创造了这个. (2认同)

Rap*_*ael 5

也可以使用Regexp.last_match(也可以通过$~)块版本访问完整版本MatchData

"5,214".gsub(/(\d),(\d)/) { |_|
    match = Regexp.last_match

    "#{match[1]}.#{match[2]}"
}
Run Code Online (Sandbox Code Playgroud)

这样可以更好地扩展到涉及更多的用例。

Nota bene,来自Ruby文档:

:: last_match对于执行模式匹配的方法的线程和方法范围是局部的。