[英]How to match an maximum length Regex in java
public static void main(String[] args) {
Pattern compile = Pattern
.compile("[0-9]{1,}[A-Za-z]{1,}|[A-Za-z][0-9]{1,}|[a-zA-Z][a-zA-Z0-9\\.\\-_/#]{2,}|[0-9]{3,}[A-Za-z][a-zA-Z0-9\\.\\-_/#]*|[0-9][0-9\\-]{4,}|[0-9][0-9\\-]{3,}[a-zA-Z0-9\\.\\-_/#]+");
Matcher matcher = compile.matcher("i5-2450M");
matcher.find();
System.out.println(matcher.group(0));
}
我认为这应该返回i5-2450M
但它实际上返回i5
问题是使用匹配的第一个交替。
在这种情况下,第二次交替( [A-Za-z][0-9]{1,}
,匹配i5
)“阴影”任何后续的交替。
// doesn't match
[0-9]{1,}[A-Za-z]{1,}|
// matches "i5"
[A-Za-z][0-9]{1,}|
// the following are never even checked, because of the previous match
[a-zA-Z][a-zA-Z0-9\\.\\-_/#]{2,}|
[0-9]{3,}[A-Za-z][a-zA-Z0-9\\.\\-_/#]*|
[0-9][0-9\\-]{4,}|
[0-9][0-9\\-]{3,}[a-zA-Z0-9\\.\\-_/#]
(请注意,帖子中的正则表达式可能存在严重问题 - 例如, 0---#
将与最后一条规则匹配 - 应该解决,但由于不是交替行为的“基本”问题。)
要解决此问题,请首先安排最具体的更改。 在这种情况下,它将把第二次交替置于其他交替条目之下。 (还要回顾其他的变化和相互作用;也许整个正则表达式可以简化?)
使用简单的单词边界( \\b
)在这里不起作用,因为-
被认为是非单词字符。 但是,根据正则表达式的含义,可以在交替周围使用锚点( $
和^
):例如^existing_regex$
。 这不会改变交替的行为,但是会导致i5
的初始匹配被回溯,从而导致后续的交替条目被考虑,因为无法在之后立即匹配输入结束。交替小组。
Java使用NFA或regex指导的风格,如Perl,.NET,JavaScript等,与sed,grep或awk不同。 一旦替代方案匹配 , 预计交替将退出 ,而不是最长匹配。
(这个问题中接受的答案使用了单词边界。)
来自模式 :
Pattern引擎执行传统的基于NFA的匹配, 具有 Perl 5中的有序交替 。
尝试遍历匹配项(即 while matcher(text).find())
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.