我的正则表达式应该过滤掉长度为8-10的大写单词,其中可能出现0-2个数字。它一直在我的所有测试中工作,但由于某种原因它被卡在下面的字符串上。并且n.group(0)
仅包含空字符串而不是匹配的“单词”。
static final Pattern PATTERN =
Pattern.compile("\\b(?=[A-Z\\d]{9,10}\\b)(?:[A-Z]*\\d){0,2}[A-Z]*\\b");
Matcher n = LONG_PASSWORD.matcher("foo ID:636152727 bar");
while (n.find()) {
String s = n.group(0);
resultArrayList.add(s);
}
为什么我的模式与ID:636152727
匹配?
我想过滤的一些例子(工作正常):
等...
答案 0 :(得分:2)
我没有比Ωmega的答案提供更好的解决方案,但我想我可以解释发生了什么。它归结为第一个\b
和最后一个\b
匹配相同的位置:在冒号后面。
这是前瞻可以匹配的第一个地方,因为它后跟九个数字和一个单词边界。然后正则表达式的下一部分尝试匹配两个数字(散布有任意数量的大写字母)后跟一个单词边界,并失败。所以它试图只匹配一个数字(同上),并再次失败。然后它尝试匹配零数字(散布着零字母),并且它成功,而不提前匹配位置。该位置仍然是一个单词边界,因此最终的\b
也会成功。
单词边界只是另一个零宽度断言,比如前瞻和后瞻。没有理由不能在同一地点使用两个或更多个;你是故意用第一个单词边界和前瞻来做的。如果将量词应用于断言(如\b+
),某些正则表达式会将其视为错误,但我认为它们中的任何一个都不会遇到此问题。这是一个罕见的例子,其中单独的单词开头和词尾结束断言,如GNU的\<
和\>
或TCL的\y
和\Y
,有所作为。
答案 1 :(得分:1)
<击>
您需要使用锚点^
和$
»
Pattern.compile("^(?=[A-Z\\d]{9,10}$)(?:[A-Z]*\\d){0,2}[A-Z]*$");
击> <击> 撞击>
使用此模式:
"(?:^|(?<=\\s))(?=[A-Z\\d]{9,10}(?:\\s|$))(?:[A-Z]*\\d){0,2}[A-Z]*(?=\\s|$)"