Java 正则所有格量词

Java 正则所有格量词,java,regex,Java,Regex,我在回答,是我回答的直接链接 您会注意到我使用了以下模式: (\\?)?&?(TXT\\{[^}]++})(&)? 在以下代码中(添加了一些与我的问题相关的调试): 其中输出为: Processing http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS} Groups 1:null,3:&am

我在回答,是我回答的直接链接

您会注意到我使用了以下模式:

(\\?)?&?(TXT\\{[^}]++})(&)?
在以下代码中(添加了一些与我的问题相关的调试):

其中输出为:

Processing http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}
Groups     1:null,3:&
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}&TXT{UE-IP,UE-Username,UE-Password}
Groups     1:null,3:null
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}&username=abcd&location={LOCATION}&password={PASS}
Groups     1:?,3:&
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}&password={PASS}

Processing http://ip:port/path?TXT{UE-IP,UE-Username,UE-Password}
Groups     1:?,3:null
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path

Processing http://ip:port/path?username=abcd&password={PASS}
Processed  http://ip:port/path?username=abcd&password={PASS}
这是完美的

现在,我的问题

当我将第一个匹配组
(\\?)?
更改为使用所有格量词时,即
(\\?)?+
,第一个项的输出变为:

Processing http://ip:port/path?username=abcd&location={LOCATION}&TXT{UE-IP,UE-Username,UE-Password}&password={PASS}
Groups     1:?,3:&
Found      TXT{UE-IP,UE-Username,UE-Password}
Processed  http://ip:port/path?username=abcd&location={LOCATION}?password={PASS}
我一辈子都搞不清楚第一组比赛的问号来自哪里

我看不到模式正确匹配所需字符串并在第一组中抓住问号的方法

我是不是错过了一些明显的东西

如果重要的话,我运行OS X Mavericks时使用的是:

java version "1.8.0"
Java(TM) SE Runtime Environment (build 1.8.0-b132)
Java HotSpot(TM) 64-Bit Server VM (build 25.0-b70, mixed mode)

我想,这与所有格量词的工作方式有关。首先,它们像贪婪的量词一样工作。从这个意义上说,他们会尽可能地匹配。但与贪婪量词不同的是,一旦匹配了某个对象,回溯后就不会放弃匹配

那么,拿你的正则表达式来说:

"(\\?)?+&?(TXT\\{[^}]++})(&)?"
它首先在
用户名
之前找到
,因此它匹配该用户名并将其存储在组1中。然后它发现下一个字符
&
用户名的
u
不匹配。因此,它会回溯,并在
处停止。因为这是作为所有格量词匹配的,所以他们不会失去匹配

现在,它继续前进。此时,组1仍然包含
。现在它与零件匹配:

&TXT{UE-IP,UE-Username,UE-Password}&
因为
是可选的,所以不匹配。但它并不能取代第一组中的任何东西

这意味着,您将从第一组中获得第一次匹配的



这似乎是Java正则表达式引擎中的一个bug,就像在Perl中一样,该组是未定义的

是吗?@raina77ow在我看来确实是这样。有点可笑,它从7u9开始就没有被修复过!很高兴知道我没有发疯。如果你把它作为一个答案,我会接受。我确认,这是完全相同的错误。然而,这可能是一种有用的行为。(有时)@CasimiretHippolyte哈!让我想起…@BoristheSpider:通过标志激活/取消激活某些行为会很酷:
模式。CRAZYMOD
是所有格量词所期望的行为-正如您指出的那样,
来自完全不同的失败匹配。在一次失败的匹配尝试后,引擎的状态不应该被清除吗?我同意@BoristheSpider,这是一个bug;由于没有匹配项,首先,捕获组不应该保留文本。@BoristheSpider很好,只是在Perl上测试了它,它按预期工作。当然是Java正则表达式引擎的一个bug。
&TXT{UE-IP,UE-Username,UE-Password}&