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

Java 正则表达式模式和匹配器问题,java,regex,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()); } 打印出

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

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

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

您可以删除
量词:

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

您可以删除
量词:

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

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

让我们来谈谈原始正则表达式的功能:

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

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

让我们来谈谈原始正则表达式的功能:

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

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

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

但是Java的正则表达式不是posix:当您像这里一样使用一个替换时,它将在第一个替换处停止,在那里它会找到一个匹配项(并且所有的替换都是从左到右计算的)

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

cat|catflap
根据输入:

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

POSIX正则表达式引擎是一种罕见的东西

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


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

对@Reimeus答案的补充,这是正确的答案

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

但是Java的正则表达式不是posix:当您像这里一样使用一个替换时,它将在第一个替换处停止,在那里它会找到一个匹配项(并且所有的替换都是从左到右计算的)

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

cat|catflap
根据输入:

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

POSIX正则表达式引擎是一种罕见的东西

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


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

我宁愿这样做

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));
    }
}
String-token=“23030G40KT”;
Pattern p=Pattern.compile(\\d{3}VRB)(\\d{2,3})(G\\d{2,3})?(KT|MPS|KMH);
匹配器m=p.Matcher(令牌);
如果(m.matches()){

对于(inti=1;i我宁愿做类似的事情

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));
    }
}
String-token=“23030G40KT”;
Pattern p=Pattern.compile(\\d{3}VRB)(\\d{2,3})(G\\d{2,3})?(KT|MPS|KMH);
匹配器m=p.Matcher(令牌);
如果(m.matches()){

对于(int i=1;i+1:原因是这个组匹配,正则表达式引擎停在这里,因为它不是posix引擎+1:原因是这个组匹配,正则表达式引擎停在这里,因为它不是posix引擎。你能描述你的功能需求吗你能描述一下你的功能需求吗?考虑到模式和你的例子,我不确定你想要实现什么