下面是一个正则表达式,它匹配一个以逗号分隔的数字列表,并且只允许输入唯一的数字:
^(?!.*\b(\d+)\b.*\b\1\b)(\d)(,(\d))*$
字符串
例如,它允许1,2,3,但不允许1,1或2,1,1。
有没有人能用简单的语言解释一下这是怎么回事?
我感到困惑的地方是否定的lookaheadAssert。
语法为:X(?!Y),它表示“搜索X,但仅当后面不跟Y时”。
参考:https://javascript.info/regexp-lookahead-lookbehind#negative-lookahead
但是在我展示的正则表达式中,它并不遵循上面的语法。那么它是如何工作的呢?
当它匹配1,2,3时,会发生什么匹配过程?
当它不匹配2,1,1时,会发生什么匹配过程?
当匹配1,2,3或2,1,1时,它们是首先与正则表达式(\d)(,(\d))*
的后续部分匹配,然后将其匹配结果Assert为与负前瞻部分(?!.*\b(\d+)\b.*\b\1\b)
匹配,还是首先运行负前瞻部分,然后运行剩余部分?
此外,如果我在负前瞻部分中删除\b
前后的.*
,则它也开始匹配1,1或2,1,1。那么,在负前瞻部分中删除的.*
的意义是什么?
注意:我想在我的Ruby代码中使用正则表达式,以防它对通知很重要。
正则表达式的源引用为
https://stackoverflow.com/a/45946721/936494
https://stackoverflow.com/a/45944821/936494的
谢谢.
2条答案
按热度按时间kcwpcxri1#
消极前瞻
字符串
跟随一个绳的缠绕锚(
^
),Assert,“情况并非如此((?!...)
)在跳过零个或多个字符后,(线路终结器除外)(.*
),则存在由一个或多个数字组成的字符串(\d+
),保存到捕获组1((\d+)
),前后都有一个单词边界(\b
),后面是一个或多个字符(行终止符除外)(.*
),后面是捕获组1的内容(\1
),前面和后面是单词边界”。因此,对于字符串
'a 12, *34 *12'
,负向前查找失败(因为'12'
前后都有一个字边界,所以是重复的),而对于字符串'a 12, *34 512'
,它会成功。(尽管重复了'12'
,第二个'12'
前面没有字边界)如果lookahead失败,则不可能有匹配,因此不计算正则表达式的其余部分。如果lookahead成功,则正则表达式引擎继续计算正则表达式的其余部分。由于正则表达式以字符串开头的锚(
^
)开始,如果满足,则前瞻不会将正则表达式的字符串指针从字符串的开头移动,在这种情况下,正则表达式实际上变为型
例如,这满足
'1,2,3'
。'1'
将保存到捕获组2(捕获组1用于前瞻),',2'
将被保存到捕获组3,'2'
将被保存到捕获组4,',3'
将被保存到捕获组3(',2'
),'3'
将被保存到捕获组4('2'
)。Demo考虑到正则表达式中跟在负前瞻后面的部分,我们可以看到负前瞻可以收紧如下1:
型
Demo的
1.为了测试正则表达式对多个字符串的影响,我在链接中使用了正向前向
(?=,|$)
(而不是(?=,|\z)
)。nfeuvbwi2#
你必须与排除一致(顶部)
字符串
与底部
型
在整个过程中使用 \d+。
如果你只需要一个数字\d,那么在整个过程中使用它。
型
https://regex101.com/r/EnAPJW/1