这就是我想要做的:
给定一个字符串12345678,commify(str)应该给我12,345,678。
要使用正则表达式和Perl来解决此问题,而解决此问题的解决方案是:
s /(?<= \ d)(?=(\ d \ d \ d)+(?!\ d))/,/ g
资料来源:掌握正则表达式
我在理解这一点时遇到的问题是我们如何捕获该字符串的“ 345”部分。我可以考虑的一件事是,正则表达式指针“ i”(这就是我的可视化方式)从1开始,另一指针“ j”遍历整个字符串并找到5到6之间的适当位置。然后我移动到2。“ j”再次遍历整个字符串,在2和3之间找到合适的位置(因为现在在5和6之间插入了逗号)。我的理解正确吗?如果没有,是否有人可以帮助我形象化这个过程?
注意:我发现了类似的问题,但是它们似乎并没有解释问题的解决方式,而是给出了确切的答案。
(?<=\d)(\d\d\d)+(?!\d)
Run Code Online (Sandbox Code Playgroud)
如何运作,从右边阅读:
(?!\d) 前瞻性断言可确保在此点之后没有数字,光标(输入中)在最后一位之后(\d\d\d)+ 匹配1个或多个三位数的组(?<=\d) 确保组的第一个数字之前还有一个数字关于回溯的更新:接受123456789
只要在光标之前找到一个数字,第一个引擎就会启动:1之后
1.23456789
Run Code Online (Sandbox Code Playgroud)
那么它会尝试匹配至少1个和三位数一样多的组
1.234.567.89
Run Code Online (Sandbox Code Playgroud)
89之后,它找不到第三位数字,并且由于负向超前而无法回溯它,因此它在开始时回溯并转到以下字符:2
12.345.678.9
Run Code Online (Sandbox Code Playgroud)
再次未能在三位一组中找到第二个数字,因此转到3
123.456.789
Run Code Online (Sandbox Code Playgroud)
现在没有更多的数字,所以它匹配。
请注意,最坏的情况是numbre是3的倍数,并且每次替换都需要这样做,因为前行不会向前移动输入光标。
包括perl一线
perl -pe 's/(?<=\d)(?=(\d{3}(?{print "matched $&.\n"}))+(?!\d(?{print "failed: $&.\n"})))/,/g' <<<123456789
Run Code Online (Sandbox Code Playgroud)