获得所有可能的匹配在一个正则表达式匹配(在Java中)?



我使用一个正则表达式来匹配几个可能的值在一个字符串中,与我的对象,在那里我需要得到所有可能的值,从我的字符串匹配如下,

如果我的字符串值是"This is the code ABC : xyz use for something".

这是我用来提取匹配器的代码,

String my_regex = "(ABC|ABC :).*";
List <String> matchers = Pattern.compile(my_regex, Pattern.CASE_INSENSITIVE)
.matcher(my_string)
.results()
.map(MatchResult::group)
.collect(Collection.toList());

我期望这2个列表项作为输出>{"ABC", "ABC:"},但我只得到一个。非常感谢您的帮助。

你所描述的并不是正则表达式引擎的工作方式。他们没有找到所有可能的变体搜索结果;他们只是消耗,给你所有的结果,继续前进。换句话说,你是否写过:

String my_regex = "(ABC|ABC :)"; // note, get rid of the .*
String myString = "This is the code ABC : xyz use for something ABC again";

然后你会得到2个结果-ABC :ABC

是的,正则表达式可以很容易地匹配ABC部分而不是ABC :部分,它仍然是有效的。然而,regexp匹配在默认情况下是"贪婪的"——它会尽可能多地匹配。对于某些运算符(特别是*+),您可以使用非贪婪变体:*?+?,它们将尽可能少地匹配。

换句话说,给定:

String regex = "(a*?)(a+)";
String myString = "aaaaa";

然后组1将匹配0a(这是可以匹配(a*?)的最短字符串,同时仍然能够将整个正则表达式匹配到输入),组2将是aaaaa

另一方面,如果你写的是(a*)(a+),那么第一组将是aaaa,第二组将是a。不可能要求regexp引擎为您提供具有'a'的所有可能长度的组合爆炸-这似乎是您想要的。java附带的regexp API没有任何选项,我所知道的任何其他regexp API也没有,所以您可能必须自己编写。我承认我没有在网上搜索所有可能的替代正则表达式引擎对java的影响,有一堆第三方库,也许其中一个可以做到。

我一开始就说了:去掉。*。这是因为否则它仍然只是一个匹配:ABC : xyz use for something ABC again是最长的可能匹配,并且给定regex引擎是贪婪的,这就是你将得到的:它是你的字符串(1匹配)的有效"解释",消耗最多-这就是它的工作方式。

NB2:贪心永远不会改变一个正则表达式是否匹配。它只是改变哪一个输入被分配给哪个组,当find()超过一次时(.results()会这样做,find()会一直这样做,直到找不到更多的匹配),你会得到哪个匹配。

最新更新