我想尝试匹配输入
<foo>
<bar>
#####<foo>
#####<bar>
Run Code Online (Sandbox Code Playgroud)
我试过#{5}?<\w+>
,但它不匹配<foo>
和<bar>
.
这种模式有什么问题,如何修复?
pol*_*nts 11
?
可选VS不愿意?
Java正则表达式(以及其他一些版本)中的元字符可以有两种截然不同的含义,具体取决于它出现的位置.紧接着重复说明符后,?
是一个不情愿的量词,而不是"零或一"/"可选"重复说明符.
因此,#{5}?
并不意味着"可选地匹配5 #
".事实上它说" #
不情愿地匹配5 ".尝试匹配"正好5,但尽可能少"可能没有多大意义,但这实际上是这种模式的意思.
解决此问题的一种方法是将可选模式分组为(…)?
.这样的事情应该适用于这个问题:
(#{5})?<\w+>
Run Code Online (Sandbox Code Playgroud)
现在?
不紧跟在重复符(即*
,+
,?
,或{…}
); 它遵循用于分组的结束括号.
或者,(?:…)
在这种情况下,您还可以使用非捕获组:
(?:#{5})?<\w+>
Run Code Online (Sandbox Code Playgroud)
这实现了相同的分组效果,但没有捕获到\1
.
java.util.regex.Pattern
:X{n}?
:X,正是ñ倍??
值得注意的是,您可以使用??
不情愿地匹配可选项目!
System.out.println("NOMZ".matches("NOMZ??"));
// "true"
System.out.println(
"NOM NOMZ NOMZZ".replaceAll("NOMZ??", "YUM")
); // "YUM YUMZ YUMZZ"
Run Code Online (Sandbox Code Playgroud)
请注意,这Z??
是一个可选项Z
,但它不情愿地匹配."NOMZ"
完整的仍然matches
是模式NOMZ??
,但在replaceAll
,NOMZ??
只能匹配"NOM"
,Z
即使它在那里也不必采取可选.
相比之下,NOMZ?
将Z
贪婪地选择匹配:如果它在那里,它将采取它.
System.out.println(
"NOM NOMZ NOMZZ".replaceAll("NOMZ?", "YUM")
); // "YUM YUM YUMZ"
Run Code Online (Sandbox Code Playgroud)
matches
是一种反对整体的模式 String