如何在Java中获取Group.Captures(来自C#中的RegEx)的行为

本文关键字:RegEx 中的 来自 Java 获取 Captures Group | 更新日期: 2023-09-27 18:21:55

我想要的是以一种最易于使用的方式在Java的正则表达式API中模仿C#正则表达式(我非常喜欢)的行为。

基本上,C#允许您访问Matches中Group对象实例的Captures属性,从而在正则表达式中捕获"嵌套"组的闭包。该功能的描述如下:MSDN。

例如,看看下面的代码:

public static void main(String[] args) {
    Pattern pattern = Pattern.compile("(abc((([''d]+)''s?)+)def''s?)+?");
    Matcher matcher = pattern.matcher("abc123def abc567 341 123 789def");
    while(matcher.find()) {
        System.out.println(matcher.group(3));
    }
}

Java输出为:

123
789

所以,正如您所看到的,Java看不到除(最后)789之外的其他捕获。在C#中,您可以在Captures属性中看到567、341、123和789。

不幸的是,我看到在Java中,我只能访问嵌套组([''d]+)的一个捕获,我看不到找到捕获嵌套组的其他捕获的方法。问题基本上是"我是不是遗漏了什么?"。

知道我可以在较大组的匹配字符串上使用另一个regex匹配器。不过,我希望在一个大的RegEx中完成这一切,它充满了评论,并且很容易在(非常酷的)工具"Regulator v2"中进行测试。我也知道上面的例子可以在没有嵌套组的情况下完成,但这只是一个基于实际日志解析器RegEx的粗略例子,其中包含>20个组,只是为了解释问题所在。

编辑:我介绍了整个Java示例,以避免对问题的误解。

如何在Java中获取Group.Captures(来自C#中的RegEx)的行为

在java中不可能实现这一点。Java Matcher类将在每个匹配中返回子组的最后一个匹配。即:

对于正则表达式:字符串a1b2c3 上的('w('d))+

返回的组将是["a1b2c3"、"c3"answers"3"]。

如果正则表达式更改为('w('d)),则它将返回匹配项:

["a1", "a1", "1"]["b2", "b2", "2"]["c3", "c3", "3"]

如果使用Matcher对象,则可以循环遍历所有匹配并获取每个匹配的组。

基本上你这样做:

while( matcher.find() ) {
  matcher.group(3); //group 0 is the entire match, group 1 and 2 are the outer groups
}   

但是,请注意,您的正则表达式需要进行一些调整,因为它将匹配例如abc567 341 123def。AFAIK如果你想要的话,你不可能在一场比赛中获得567、341和123组。

您可以使用这个表达式来获得abcdef之间的数字组,然后在第二步中拆分这些组:(?<=abc)((?:'d+'s?)+)(?=def)

此表达式将返回123567 341 123,并且将它们拆分为空白将导致具有每个单独数字的字符串数组,即"123".split("''s+")->{"123"}"567 341 123".split("''s+")->{"567", "341", "123"}