我正在尝试匹配像
这样的输入<foo>
<bar>
#####<foo>
#####<bar>
我尝试了#{5}?<\w+>
,但它与<foo>
和<bar>
不匹配。
这种模式有什么问题,如何解决?
答案 0 :(得分:11)
?
for optional vs reluctant Java正则表达式中的?
元字符(以及其他一些版本)可能有两种截然不同的含义,具体取决于它出现的位置。紧跟重复说明符后,?
是一个不情愿的量词,而不是“零或一”/“可选”重复说明符。
因此,#{5}?
并不意味着“可选地匹配5 #
”。事实上它说“不情愿地匹配5 #
”。尝试匹配“确切地说5,但尽可能少”,这可能没有多大意义,但这实际上就是这种模式的含义。
解决此问题的一种方法是将可选模式分组为(…)?
。这样的事情应该适用于这个问题:
(#{5})?<\w+>
现在?
没有立即跟随重复说明符(即*
,+
,?
或{…}
);它遵循用于分组的结束括号。
或者,您也可以在这种情况下使用非捕获组(?:…)
:
(?:#{5})?<\w+>
这实现了相同的分组效果,但没有捕获到\1
。
java.util.regex.Pattern
:X{n}?
: X ,完全 n 次??
值得注意的是,您可以使用??
来勉强匹配可选项目!
System.out.println("NOMZ".matches("NOMZ??"));
// "true"
System.out.println(
"NOM NOMZ NOMZZ".replaceAll("NOMZ??", "YUM")
); // "YUM YUMZ YUMZZ"
请注意,Z??
是可选的Z
,但它不情愿地匹配。 "NOMZ"
完整matches
模式NOMZ??
,但在replaceAll
,NOMZ??
只能与"NOM"
匹配,而不必采取Z
可选NOMZ?
,即使它在那里。
相比之下,Z
会贪婪地匹配可选的 System.out.println(
"NOM NOMZ NOMZZ".replaceAll("NOMZ?", "YUM")
); // "YUM YUM YUMZ"
:如果它在那里,它就会接受它。
matches
String
针对整个 {{1}}的模式答案 1 :(得分:2)
将您的#
匹配放在子模式中:
(#{5})?<\w+>