我使用一个正则表达式来匹配几个可能的值在一个字符串中,与我的对象,在那里我需要得到所有可能的值,从我的字符串匹配如下,
如果我的字符串值是"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()
会一直这样做,直到找不到更多的匹配),你会得到哪个匹配。