我是初学者,试图学习如何在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
,$1
为frok dork
,$3
为dumb
,符合预期。
但是,对于test1 = frok dork is 10 Foo
,我预计匹配会失败。相反,我将$1
设为frok
,将$3
设为dork
。为什么dork
与\\w+
匹配而不是((frok | dork )*)
,与之前的情况相同?
我在这里搜索了SO,但这些帖子(Java regular expression with groups,Regular expressions, groups issue,Is 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?)未解决此问题。
答案 0 :(得分:3)
一张图片胜过千言万语!
所以这里是你的小组 - 解释正则表达式的哪一部分符合什么。
您需要一个正则表达式调试器
查看事物匹配或失败的最佳方法是使用正则表达式调试器。我一直在使用正则表达式,,如果没有调试工具,我就不会这样做。
在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+)
表示可以有任意数量的frok
或dork
s后跟一个单词。在第一个测试中,frok
和dork
都与第一个组匹配,dumb
与下一个匹配。但是在第二次测试中,为了匹配模式,dork
必须被计为单个跟随单词。因此,只能在初始组中计算frok
。
答案 3 :(得分:1)
有标记组(
表达式 )
,并且有非标记组(?:
表达式 )
。你看到了不同之处。打开括号后,非标记组的?:
。
标记组表达式找到的字符串可以使用$1
,$2
,...或\1
,\2
,....进行反向引用。< / p>
示例中的OR表达式应该是非标记组,因为内部括号仅适用于应该应用0次或更多次的OR表达式。
答案 4 :(得分:0)
您在正则表达式中嵌套了组:((frok |dork )*)
因此frok
被捕获两次。然后,正如您所猜测的那样,dork
(\\w+)