为什么不呢?在这种模式中作为可选的重复说明符工作?

hua*_*gli 2 java regex

我想尝试匹配输入

<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.

参考

相关问题


奖金材料:怎么样 ??

值得注意的是,您可以使用??不情愿地匹配可选项目!

    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)

相关问题