如何仅在某些行上获得多个 Java 正则表达式匹配

Posted

技术标签:

【中文标题】如何仅在某些行上获得多个 Java 正则表达式匹配【英文标题】:How can I get multiple Java regex matches on only certain lines 【发布时间】:2018-04-24 05:17:32 【问题描述】:

我正在调用一个我无法更改的 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 各一行,包括 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:”开头的行。

或者,更笼统地说,我希望多行模式中的多个匹配项,但只能来自具有特定前缀的行。

【问题讨论】:

(^(?:good|better): *thing\d2.*) regex101.com/r/8EbDRA/1 这只会匹配第一组,而不是所有的行 他说他想要多个匹配,这就是那个模式的作用。您可以通过与((?:^(?:good|better): *thing\d2.*\n)+)987654325@ 非常相似的内容在一场比赛中获得所有内容 【参考方案1】:

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

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

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


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

(?<=^(?:good|better):.0,1000)(thing[0-9]+)

【讨论】:

今天我了解了 \G 锚。非常感谢!顺便说一句, (?!^) 是做什么的?我知道它对线锚的开始是负前瞻,但为什么需要它? 不错的正则表达式,但您不需要对 start (?!^) 进行负面展望,因为行从不以逗号开头。即这有效:"(?:\\G,|^(?:good|better):)\\s*(thing\\d+)" @Matt 不需要。看我的评论。 @MattMalone: 因为\G 也匹配字符串的开头。添加(?!^) 可以避免这种情况,但实际上,如果您没有以逗号开头的行,则可以将其删除。

以上是关于如何仅在某些行上获得多个 Java 正则表达式匹配的主要内容,如果未能解决你的问题,请参考以下文章

Pandas:在 500 万行上使用 Apply 和正则表达式字符串匹配

正则表达式:匹配多个平衡组

如何仅在某些行上显示图像按钮

Ruby Regexp 组匹配,在 1 行上分配变量

Android怎么用正则表达式替换字符串某些字符?

Java正则表达式匹配地址获得省市县