我试图理解为什么我没有从正则表达式中获得预期的结果。
我已经知道什么是负面预测(显然不是:-))而且星号是重复的零次或多次。
看看这个正则表达式:
a(?![^3])
这将匹配a
之后没有non-3
的匹配。
所以看看这个测试字符串,粗体部分就是匹配:
一个 3333335
好的
另外 - 如果我将正则表达式更改为:
a(?![^3]+) //notice "+"
它仍将匹配:
一个 3333335
这将匹配a
,后面没有非3(至少一个)
问题
我的问题在于*
:
让我们将正则表达式更改为:
a(?![^3]*)
这不符合
a3333335
但我的问题是 - 为什么?
根据图纸:
a
不应该跟着: 没有或 非3
但这是发生的事情:a
后面没有任何内容 AND 后面没有非三维
那么为什么它不匹配?
让我的生活变得更加困难:
看看这个正则表达式:
a(?![^3]*7)
这将匹配:
一个 3333335
这里发生了什么?
答案 0 :(得分:6)
问题是星号可以生成空字符串(""
),你可以说每个字符和下一个字符之间的,都有一个空字符串强>
鉴于正则表达式:
a(?![^3]*)
并且您使用a33333
进行查询,您或多或少地说:如果在a
之后有非零或更多次非重复,则拒绝,但是有这样的重复:空字符串,所以甚至没有捕获一个3
,它将拒绝。因此匹配如下:
a (?![^3]*)
"a" "" "33333"
(引号标记字符串,此处没有字符)
你可以这么说,负面前瞻,正常表达式上的 Kleene明星总会拒绝(必须小心,在句子中我的意思是Kleene明星统一了"整个"正则表达式,这 not 意味着包含Kleene星的负向前瞻总是拒绝。
您的图片也显示了这一点:
它说如果没有跟着,就意味着它与盒子里面的内容不匹配。问题是,它不需要单个字符到达框的末尾。
这不适用于a(?![^3]*7)
:在这里你说" *如果您遇到零或更多非3 ,然后是七,则拒绝。由于正则表达式[^3]*7
与3333335
不匹配,因此前瞻不会拒绝匹配。
答案 1 :(得分:5)
问题是*
会重复 零 或更多次。包含零非3s(也称为空字符串)。没有什么不代表字符串的结尾,它意味着字面意思 nothing (空字符串)。
7
的示例有效的原因是因为前瞻会尝试匹配尽可能多的非3。在a
之后的位置,即零非3s。之后,它将尝试完全匹配一个7 。但是下一个字符 3 ,因此前瞻不会使a
的匹配失败。
答案 2 :(得分:3)
理解原因:
a(?![^3]*)
无法匹配您可以将前瞻更改为:
a(?!.*)
也会失败并且理由与你的前瞻断言相同,a
后面跟包含空字符串的任何内容都不会返回false,因此你的正则表达式总会失败。< / p>
第二个正则表达式是这样的:
a(?![^3]*7)
成功,因为输入中确实没有non-3
的0个或更多,后跟7
。
如果您将输入更改为例如a7
然后它将失败。
答案 3 :(得分:0)
问题在于*的行为与其他任何地方的行为方式相同。
[^ 3] * 会匹配每个字符串,因为它匹配“尽可能多的不包含3个字符串”。
a(?![^ 3] * 7)应匹配“任何'a'后面没有尽可能多的'3',包括无和'7'。”这相当于“任何'a'没有后跟7,除非他们被'3'分开。”