4

我正在调用一个我无法更改的 API。也就是说,我不能将其作为两个连续的正则表达式或类似的东西来执行。API 是这样编写的(当然是简化的):

void apiMethod(final String regex) {
    final String input = 
        "bad:    thing01, thing02, thing03 \n" +
        "good:   thing04, thing05, thing06 \n" +
        "better: thing07, thing08, thing09 \n" +
        "worse:  thing10, thing11, thing12 \n";

    final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);

    final Matcher matcher = pattern.matcher(input);

    while (matcher.find()) {
        System.out.println(matcher.group(1));
    }
}

我像这样调用它:

apiMethod("(thing[0-9]+)");

我想打印出六行,从 04 到 09 各一行,包括在内。到目前为止,我还没有成功。我尝试过的一些方法不起作用:

  • "(thing[0-9]+)" - 这匹配所有 12 个东西,这不是我想要的。
  • "^(?:good|better): (thing[0-9]+)" - 仅匹配事物 4 和 7。
  • "^(?:(?:good|better): .*)(thing[0-9]+)" - 仅匹配事物 6 和 9。
  • "(?:(?:^good:|^better:|,) *)(thing[0-9]+)" - 这匹配除 1 和 10 之外的所有内容。

还有更多,不胜枚举。我尝试了各种后视,无济于事。

我想要的是匹配“thing[0-9]+”的所有字符串,但只有那些以“good:”或“better:”开头的行。

或者,更一般地说,我想要来自多行模式的多个匹配项,但只能来自具有特定前缀的行。

4

1 回答 1

5

您必须使用\G基于模式(在多行模式下):

(?:\G(?!^),|^(?:good|better):)\s*(thing[0-9]+)

锚点强制匹配是连续的\G,因为它匹配最后一次成功匹配之后的位置。


如果行很短,您也可以使用有限的可变长度后视来做到这一点:

(?<=^(?:good|better):.{0,1000})(thing[0-9]+)
于 2017-11-10T22:37:49.603 回答