为什么这个正则表达式在PHP中正常工作但在Java中不正常?

时间:2013-11-09 23:34:47

标签: java php regex

所以我有这个正则表达式

 ^<(.*?)>

应该匹配第一个开始标记的内容。 然而,虽然这适用于PHP,但在java中它匹配第一个&lt;之间的所有内容。和最后一个&gt;。

例如,当它运行时:

<tag1 attr1="val1"><tag2></tag2></tag1>

PHP匹配:

 tag1 attr1="val1"

,而Java匹配

tag1 attr1="val1"><tag2></tag2></tag1

2 个答案:

答案 0 :(得分:2)

String s1="<tag1 attr1=\"val1\"><tag2></tag2></tag1>";
Pattern p = Pattern.compile("^<(.*?)>");
Matcher m = p.matcher(s1);
while(m.find()) {
    System.out.println(m.group(1));
}

这是我测试的代码,它返回tag1 attr1="val1"

然后,在评论中,您说您使用的是matches方法:这就是区别。

虽然find方法检查匹配正则表达式的字符串的任何部分,但matches方法要求整个字符串与给定的正则表达式匹配。

所以,在你的例子中:

while(m.find()) {
    System.out.println(m.group(1)); //will print   tag1 attr1="val1"
}

if (m.matches()) { //will evaluate the regex as ^<(.*?)>$
    System.out.println(m.group(1)); //will print    tag1 attr1="val1"><tag2></tag2></tag1
}

答案 1 :(得分:0)

我第一次没有发现的是你使用非贪婪的重复(*?)明确

但我原来的观点仍然存在:

  • 在这方面,PHP和Java正则表达式的语义没有区别。

  • 使用Java find与Java matches不会改变正则表达式的语义。具体而言,它不会将非贪婪变为贪婪,反之亦然。 (正如您在评论中所假设的那样。)

find成功(多次)和matches的原因并不完全取决于matches必须与整个字符串匹配的事实。