繁体   English   中英

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

[英]Regex Pattern and Matcher issue

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

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

其他答案(例如@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})? 确实匹配(空字符串!)因此,甚至不考虑下一个替换。

接下来的两个空白行也与该交替匹配。 请注意,如果匹配为空,则正则表达式引擎将在输入中移动一个字符(否则,将导致无限循环!)。

我宁愿做类似的事情

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM