正则表达式模式和匹配器问题

时间:2013-01-15 23:41:09

标签: java regex

我不明白为什么我的正则表达式似乎不起作用。这是一个例子:

String token = "23030G40KT";

Pattern p = Pattern
                .compile("(\\d{3}|VRB)|(\\d{2,3})|(G\\d{2,3})?|(KT|MPS|KMH)");
Matcher m = p.matcher(token);

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

打印出来:

230
30
G40

(以下两个空白行未显示)

我想打印:

230
30
G40
KT

没有空行。我需要改变什么?

4 个答案:

答案 0 :(得分:4)

您可以删除?量词:

Pattern.compile("(\\d{3}|VRB)|(\\d{2,3})|(G\\d{2,3})|(KT|MPS|KMH)")

答案 1 :(得分:1)

原始正则表达式不起作用的原因在其他答案中有很好的描述,例如@ Reimus's。但是,我想帮助您进一步简化它。你的正则表达式看起来很复杂但实际上非常简单,如果你把它分解。

让我们谈谈你的原始正则表达式的作用:

\\d{3} - 三位小数

| - 或

VRB - “VRB”

| - 或

\\d{2,3} - 2或3位小数

| - 或

G\\d{2,3} - “G”后跟2或3位小数

| - 或

(KT|MPS|KMH) - “KT”或“MPS”或“KMH”

所以基本上你只是有很多东西或者在一起。其中一些是冗余的(例如“3位小数”和“2或3位小数”)。将它们组合在一起可以减少需要分组的情况。

使用这个更简单的正则表达式可以获得相同的结果:

Pattern.compile("G?\\d{2,3}|KT|MPS|KMH|VRB");

答案 2 :(得分:1)

@Reimeus答案的附录,这是正确答案。

如果正则表达式引擎遵循POSIX,它总是会寻找最左边,最长的匹配。注意:最长。

但是Java的正则表达式不是posix:当你在这里使用替换时,它会停在第一次交替,它找到一个匹配(并且所有的交替从左到右进行评估) )。

例如,如果您尝试匹配正则表达式:

cat|catflap

反对输入:

catflap

Java的正则表达式引擎将匹配cat。 POSIX正则表达式引擎将匹配catflap

POSIX正则表达式引擎很少见。

在您的交替中,(G\d{2,3})? 匹配(空字符串!)。因此,甚至不会考虑下一个更改。

以下两个空行也是该交替的匹配项。请注意,在空匹配的情况下,正则表达式引擎将在输入中移动一个字符(否则您将获得无限循环!)。

答案 3 :(得分:0)

我宁愿做类似

的事情
String token = "23030G40KT";
Pattern p = Pattern.compile("(\\d{3}|VRB)(\\d{2,3})(G\\d{2,3})?(KT|MPS|KMH)");
Matcher m = p.matcher(token);

if(m.matches()) {
    for (int i = 1; i <= m.groupCount(); ++i) {
        System.out.println(m.group(i));
    }
}