Python和Java中相同正则表达式的不同行为

时间:2015-05-29 10:24:50

标签: java python regex

首先,我道歉,因为我不太了解正则表达式。

我正在使用正则表达式来匹配字符串。我在Python命令行界面中测试了它,但是当我在Java中运行它时,它产生了不同的结果。

Python执行:

re.search("[0-9]*[\\.[0-9]+]?[^0-9]*D\\([M|W]\\)\\s*US", "9.5 D(M) US");

将结果显示为:

<_sre.SRE_Match object; span=(0, 11), match='9.5 D(M) US'>

但Java代码

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

class RegexTest {
    private static final Pattern FALLBACK_MEN_SIZE_PATTERN = Pattern.compile("[0-9]*[\\.[0-9]+]?[^0-9]*D\\([M|W]\\)\\s*US");

    public static void main(String[] args) {
    String strTest = "9.5 D(M) US";
    Matcher matcher = FALLBACK_MEN_SIZE_PATTERN.matcher(strTest);
        if (matcher.find()) {
            System.out.println(matcher.group(0));
        }
    }
}

将输出显示为:

5 D(M)US

我不明白为什么它的行为方式不同。

2 个答案:

答案 0 :(得分:5)

以下是在Java和Python中使用相同的模式:

"[0-9]*(?:\\.[0-9]+)?[^0-9]*D\\([MW]\\)\\s*US"

请参阅PythonJava演示。

在Python中,[\\.[0-9]+]?被视为2个子图案:[\.[0-9]+(1个或更多.个,[个或数字)和]?( 0或1 ])。了解your regex works in Python here的方式。或者,与捕获组进行更多分离,here

在Java中,它被读作一个单个字符类(即[]里面的被忽略,因为它们无法被正则表达式引擎正确解析,因此整个子模式代表0或1 .,一个数字或+),因为它是可选的,它没有捕获任何东西(你可以在Visual Regex Tester获得一个视觉提示,输入{ {1}}作为输入,123.+[]作为正则表达式。

最后一步:[\.[0-9]+]?代表[M|W]M|,而我认为您的意思是W = [MW]M

答案 1 :(得分:1)

我不是Python专家,所以我不能告诉你为什么它适用于Python,但在Java中,你的问题是[\\.[0-9]+]?部分。你可能认为它是(\\.[0-9]+)?

实际上,它是[]中的字符列表,后跟?。也就是说,表达式的这一部分只匹配单个或零个字符,因此它不能与.5匹配。

以下是匹配尝试的说明:

Graphical demonstration of matching in Java

现在,如果您的模式使用的是()而不是[],那就是结果:

enter image description here