0

我想将输入字符串拆分为以<word> 可以是“block”、“vers”或“refr”开头\begin{<word>}和结尾的块,并在每个块上执行 addBlock()。\end{<word>}在包含其中两个块的字符串上尝试此方法时,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());
    }
}
4

2 回答 2

0

这永远不会给出一个以上的结果,因为 .* 会吃掉结束标记前面的每个字符。

groupCount() 不返回匹配的数量,而是返回捕获组的数量。也在这里解释:https ://stackoverflow.com/a/2989061/2947592

于 2013-11-12T22:04:11.510 回答
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,因为pattern 中有 2 个捕获组。

于 2013-11-12T22:16:00.627 回答