首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >此正则表达式行超出了我的理解"(?=(?:\d{3})++(?!\d))“

此正则表达式行超出了我的理解"(?=(?:\d{3})++(?!\d))“
EN

Stack Overflow用户
提问于 2012-04-07 23:51:36
回答 3查看 818关注 0票数 2

我对基本的reg-ex很满意。但是,这行代码用于使大量的千分离超出了我的知识和谷歌它相当多,也不能满足我的好奇心。你们谁能花点时间给我解释一下下面这行代码吗?

代码语言:javascript
复制
someString.replaceAll("(\\G-?\\d{1,3})(?=(?:\\d{3})++(?!\\d))", "$1,");

我特别不理解正则表达式结构"(?=(?:\d{3})++(?!\d))"

在此之前非常感谢。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-04-08 00:08:48

"(?=(?:\d{3})++(?!\d))"是一个lookahead assertion

它的意思是“只有在((我们不需要捕获的三个数字)重复一次或多次(并再次重复一次或多次)(后面不跟数字)的情况下才匹配”。请参阅这个关于(?:...)表示法的explanation。它被称为非捕获组,这意味着你在比赛后不需要引用这个组。

"(\\G-?\\d{1,3})"是应该实际匹配的部分(但仅当满足上述条件时)。

编辑:我认为+必须是一个特殊的字符,否则它只是一个加号。如果它是一个特殊字符(快速搜索显示为it is in Java, too),则第二个字符是多余的。

编辑2:多亏了Alan Moore,它现在变得清晰了。第二个+意味着所有匹配,所以它意味着如果在检查了尽可能多的3位数组后,它不会发现它们后面没有非数字,引擎将立即放弃,而不是后退一个3位数组。

票数 3
EN

Stack Overflow用户

发布于 2012-04-08 00:21:36

这个表达式中包含了一些高级内容。首先,最简单的:\d{3}恰好是三位数。这是你的数千人。

然后:++是+的变体(这意味着一个或多个),但所有格,这意味着它将吃掉数千个。我不完全确定为什么这是必要的。

?:意味着它是一个非捕获组-我认为这只是出于性能原因,可以省略。

?=是一个积极的先行检查-我认为这意味着它只检查该组是否存在,而不会计入匹配的字符串-这意味着它不会被替换。

?!是一个负向先行-我不太理解这一点,但我认为它意味着它必须不匹配,这反过来意味着在匹配序列的末尾不能有另一个数字。这确保了第一组得到正确的数字。例如,10000只能作为10(000)匹配,而不是1(000)0,如果你明白我的意思。

通过lookaheads,如果我理解正确(我还没有测试它),只有第一组实际上会被替换,因为它是匹配的那一组。

票数 3
EN

Stack Overflow用户

发布于 2012-04-08 03:46:14

对我来说,这个正则表达式中最有趣的部分是\G。我花了一段时间才记起它的作用:防止在分数部分中添加逗号(如果有)。如果正则表达式只是:

代码语言:javascript
复制
(-?\d{1,3})(?=(?:\d{3})++(?!\d))

...this编号:

代码语言:javascript
复制
12345.67890

...would的结尾为:

代码语言:javascript
复制
12,345.67,890

但是将\G添加到开头意味着匹配只能从字符串的开头或前一个匹配结束的位置开始。所以它不匹配345,因为它后面跟着.,它也不匹配67,因为它必须跳过一些字符串才能做到这一点。因此它正确地返回:

代码语言:javascript
复制
12,345.67890

我知道这不是问题的答案,但我认为它值得一提。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/10055885

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档