我想将输入字符串拆分为以\begin{<word>}
开头并以\end{<word>}
结尾的块,其中&lt; word&gt;可以是“block”,“vers”或“refr”,并在每个块上执行addBlock()。在包含其中两个块的字符串上尝试此方法时,m.groupCount()
正确返回2,但m.find()
返回false。怎么会这样? m.group()
会抛出异常。
private void addBlocks(String in) {
Pattern p = Pattern.compile("\\\\begin\\{(vers|refr|block)\\}.*\\\\end\\{(vers|refr|block)\\}");
Matcher m = p.matcher(in);
while (m.find()) {
addBlock(m.group());
}
}
编辑: 是的,那里有几个错误。正则表达式是一个痛苦的屁股,它不是非常直观,并没有那么多明智的帮助在线。以下是最终有效的代码:
private void addBlocks(String in) {
Pattern p = Pattern.compile("\\\\begin\{(block|vers|refr)\\}(.|$)*?\\\\end\\{(block|vers|refr)\\}", Pattern.DOTALL);
Matcher m = p.matcher(in);
while (m.find()) {
addBlock(m.group());
}
}
答案 0 :(得分:0)
这将永远不会给出多个结果,因为。*会占用结束标记之前的每个字符。
groupCount()不返回匹配数,而是返回捕获组数。此处还解释了:https://stackoverflow.com/a/2989061/2947592
答案 1 :(得分:0)
一般来说,您的代码适合我,至少对于此测试调用:
addBlocks("foo bar \\begin{vers}bla\\end{vers}foo bar baz \\begin{refr}bla2\\end{refr} bla");
但是,由于贪婪的addBlock()
量词,您的正则表达式最多会调用*
一次。您可能更愿意使用*?
量词:
Pattern p = Pattern.compile("\\\\begin\\{(vers|refr|block)\\}.*?\\\\end\\{(vers|refr|block)\\}");
使用*?
量词,您将获得上述测试调用的两个匹配项。
如果某些输入没有匹配,那么m.find()
将正确返回false
并且m.group()
将不会被调用(因此不会抛出任何IllegalStateException
) 。与输入字符串无关,m.groupCount()
对于您的特定正则表达式始终为2,因为模式中有2个捕获组 。