[英]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.