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);

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

打印出来:

230
30
G40

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

我想打印:

230
30
G40
KT

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

4

4 回答 4

4

您可以删除?量词:

Pattern.compile("(\\d{3}|VRB)|(\\d{2,3})|(G\\d{2,3})|(KT|MPS|KMH)")
于 2013-01-15T23:46:09.530 回答
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");
于 2013-01-15T23:47:49.603 回答
1

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

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

但是 Java 的正则表达式不是 posix:当您像在此处那样使用交替时,它将在找到匹配项的第一个交替处停止(并且所有交替都从左到右进行评估)。

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

cat|catflap

反对输入:

catflap

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

并且 POSIX 正则表达式引擎是罕见的。

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

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

于 2013-01-15T23:50:16.690 回答
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));
    }
}
于 2013-01-15T23:51:18.730 回答