相同正则在Java和Python中结果不同

0 投票
3 回答
1879 浏览
提问于 2025-04-17 12:55

Java代码:

import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class RegExpTest {
    public static void main(String[] args) {

        String str = "X-Value = -0.525108, Y-Value = 7.746691, Z-Value = 5.863008, Timestamp(milliseconds) = 23001";
        String p = "Value = (.*?), ";
        Pattern pattern = Pattern.compile(p);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()){
             System.out.println(matcher.group(1));
             System.out.println(matcher.group(2));
             System.out.println(matcher.group(3));
        }
    }
}

Java代码的输出结果:

$ java RegExpTest 
-0.525108
Exception in thread "main" java.lang.IndexOutOfBoundsException: No group 2
        at java.util.regex.Matcher.group(Matcher.java:487)
        at RegExpTest.main(RegExpTest.java:15)
$ 

Python代码(在解释器中):

>>> import re
>>> re.findall("Value = (.*?), ", 'X-Value = -0.525108, Y-Value = 7.746691, Z-Value = 5.863008, Timestamp(milliseconds) = 23001;')
['-0.525108', '7.746691', '5.863008']
>>> 

那么,为什么Java无法匹配所有的匹配项呢?

3 个回答

0

因为你用错了。

matcher.group() 是用来获取在一次匹配中各种捕获组的值。你只有一个捕获组(也就是你模式中的一对括号)。

matcher.find() 是一个方法,如果你反复调用它,它会返回下一个匹配的结果。通常是在一个 while 循环中使用,比如:

    while (matcher.find()){
         System.out.println(matcher.group(1));
    }

想了解更多,可以查看 这里

2

Java中的java.util.regex.Matcher.find方法是用来寻找下一个匹配的值,而不是所有匹配的值。如果你把if改成while,那么你就能得到你想要的结果。

...
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
    System.out.println(matcher.group(1));
...
7

这是因为在Java中,括号用来表示一个捕获组。

你的正则表达式里只有一组没有转义的(也就是捕获的)括号,就是(.*?)

组1里包含了匹配到的值。

没有组2是因为你的正则表达式里没有第二组括号。

在Java的例子中,你想要循环遍历所有的匹配项,并打印matcher.group(1)

while ( matcher.find() ) {
    System.out.println(matcher.group(1));
}

注意这个while,它会循环遍历所有的匹配项,并告诉你每个匹配的组1是什么。

撰写回答