我需要多次匹配相同模式的字符序列。
例如:对于输入Some words <firstMatch> some words <secondMatch> some more words <ThirdMatch>
,我需要<firstMatch>
,<secondMatch>
,<thirdMatch>
我尝试过这样的事情:
String input = "Some words <firstMatch> some words <secondMatch> some more words <ThirdMatch>";
Pattern pattern = Pattern.compile( ".*(\\<.*\\>).*" );
Matcher m = pattern.matcher( input );
while ( m.find() ) {
System.out.println( m.group( 1 ) );
}
我得到的只是ThirdMatch
任何帮助?
答案 0 :(得分:4)
为什么您的模式会失败?
.*(\\<.*\\>).*
会引发很多回溯。首先,.*
匹配除了换行符之外的任何0+字符,基本上是整行。然后,正则表达式引擎回溯试图适应后续模式(<.*>).*
。当它找到<
(从头到尾)时,它将再次抓住整行,并继续回溯搜索>
。找到后,最后一个.*
只匹配该行的其余部分。请注意,如果引擎在>
之后未能找到<
,则回溯将重复搜索,从而使此模式效率低下。注意:<
和>
不必以Java正则表达式模式进行转义,它们不是特殊的正则表达式元字符。
<强>解决方案强>
使用基于negated character class的简单"<[^>]*>"
模式:
String input = "Some words <firstMatch> some words <secondMatch> some more words <ThirdMatch>";
Pattern pattern = Pattern.compile( "<[^>]*>" );
Matcher m = pattern.matcher( input );
while ( m.find() ) {
System.out.println( m.group(0) ); // = m.group(), the whole match value
}
请参阅Java demo
<[^>]*>
将匹配<
,除>
以外的0 +字符,然后>
。由于您在Matcher#find()
块中使用while
,因此您会在输入字符串中找到所有非重叠匹配项,但您需要访问.group(0)
(等于.group()
,整个匹配值),而不是.group(1)
。
答案 1 :(得分:2)
您可以使用正则表达式
[^<]*<([^>]*)>
测试字符串
Some words <firstMatch> some words <secondMatch> some more words <ThirdMatch>
匹配字符串
Match 1
Group 1. 12-22 `firstMatch`
Match 2
Group 1. 36-47 `secondMatch`
Match 3
Group 1. 66-76 `ThirdMatch`
答案 2 :(得分:1)
.*
是greedy - 它会匹配下一个模式的最终匹配所能提供的所有内容...您可以通过在{{1}之后添加问号来使其变得非贪婪}符号如此匹配任何字符,任何次数,而不是贪婪将是*
,你的模式将是:
.*?
然而,这只会让你到达那里。如果你知道你的模式匹配了多少次,你可以把它放到你的模式中,例如
Pattern pattern = Pattern.compile( ".*?(\\<.*\\>).*?" );
三场比赛。
答案 3 :(得分:1)
你去:)
while(std::getline)