分组的正则表达式不直观地匹配?

时间:2014-06-23 05:35:17

标签: java regex

我是初学者,试图学习如何在Java中使用正则表达式。通过一些在线教程,我编写了以下示例代码来教自己如何使用分组运行正则表达式,但结果有点不直观。

String pattern = "((frok |dork )*)(\\w+) is (\\d+) Foo";
System.out.println(test1.matches(pattern));
System.out.println(test1.replaceAll(pattern, "$1"));        
System.out.println(test1.replaceAll(pattern, "$3"));

使用test1 = frok dork dumb is 10 Foo$1frok dork$3dumb,符合预期。

但是,对于test1 = frok dork is 10 Foo,我预计匹配会失败。相反,我将$1设为frok,将$3设为dork。为什么dork\\w+匹配而不是((frok | dork )*),与之前的情况相同?

我在这里搜索了SO,但这些帖子(Java regular expression with groupsRegular expressions, groups issueIs there a way to use a list of string parameters with a regular expression (with groups) to construct a new string?Regular expression with variable number of groups?)未解决此问题。

5 个答案:

答案 0 :(得分:3)

一张图片胜过千言万语!

所以这里是你的小组 - 解释正则表达式的哪一部分符合什么。

RegexBuddy Grops

您需要一个正则表达式调试器

查看事物匹配或失败的最佳方法是使用正则表达式调试器。我一直在使用正则表达式,如果没有调试工具,我就不会这样做。

在Windows上,正则表达式调试器的Rolls是RegexBuddy。它由 The Regex Cookbook 的作者Jan Goyvaerts和几个基于正则表达式的工具开发。在线,regex101非常好。

答案 1 :(得分:2)

  

但是,对于test1 = frok dork is 10 Foo,我预计匹配会失败。相反,我将$1设为frok,将$3设为dork。为什么dork\\w+匹配而不是((frok | dork )*),与之前的情况相同?

这里的第一句话就是你问题的答案。 ((frok |dork )*) 希望尽可能多地匹配frok dork 的出现次数;但最重要的考虑因素是,它希望正则表达式匹配成功。如果正则表达式的给定部分必须匹配一点点才能使整个匹配成功,那么就这样吧。

有关详细信息,我建议使用Google搜索正则表达式 + 回溯贪婪 nongreedy

答案 2 :(得分:1)

((frok |dork )*)(\\w+)表示可以有任意数量frokdork s后跟一个单词。在第一个测试中,frokdork都与第一个组匹配,dumb与下一个匹配。但是在第二次测试中,为了匹配模式,dork必须被计为单个跟随单词。因此,只能在初始组中计算frok

答案 3 :(得分:1)

有标记组( 表达式 ),并且有非标记组(?: 表达式 )。你看到了不同之处。打开括号后,非标记组的?:

标记组表达式找到的字符串可以使用$1$2,...或\1\2,....进行反向引用。< / p>

示例中的OR表达式应该是非标记组,因为内部括号仅适用于应该应用0次或更多次的OR表达式。

答案 4 :(得分:0)

您在正则表达式中嵌套了组:((frok |dork )*)因此frok被捕获两次。然后,正如您所猜测的那样,dork

会捕获(\\w+)