所以我有这个正则表达式
^<(.*?)>
这应该与第一个开始标签的内容相匹配。然而,虽然这在 PHP 中有效,但在 java 中,它匹配第一个 < 和最后一个 > 之间的所有内容。
例如,当它在此运行时:
<tag1 attr1="val1"><tag2></tag2></tag1>
PHP 匹配:
tag1 attr1="val1"
而 Java 匹配
tag1 attr1="val1"><tag2></tag2></tag1
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
}
我第一次没有发现的是您明确使用非贪婪重复(*?
)。
但我原来的观点仍然成立:
在这方面,PHP 和 Java 正则表达式的语义没有区别。
使用 Javafind
与 Javamatches
并不会改变正则表达式的语义。具体来说,它不会将非贪婪翻转为贪婪,反之亦然。(正如您在评论中所假设的那样。)
find
成功(多次)并且matches
没有成功的原因完全取决于matches
必须匹配整个字符串的事实。