在Java中处理重复的正则表达式组名称(C#翻译)



我正在尝试将一段C#代码翻译成Java,虽然我对这两种代码都很熟悉,但我对正则表达式库不是很熟悉。

在MSDN中,他们给出了这个例子

String pattern = @"D+(?<digit>d+)D+(?<digit>d+)?";

这个输出(我看到他们使用的是捕获索引,而不是组名本身)

Match: abc123def456
Group 1: 456
Capture 0: 123
Capture 1: 456

有了这个纸币

组名可以在正则表达式中重复。例如,可以将多个组命名为数字,如下例所示。在名称重复的情况下,Group对象的值由输入字符串中最后一次成功捕获的值确定。


所以这可能是一个糟糕的例子(因为我的实际代码没有使用数字),但无论如何。。。

将其转换为Java,它对第二个<digit>并不太满意。

String pattern = "\D+(?<digit>\d+)\D+(?<digit>\d+)?"
Pattern p = Pattern.compile(pattern);
String matchMe =  "abc123def456";

和在Pattern.compile的错误

Named capturing group <digit> is already defined

我想,完全删除除了姓氏之外的所有名字将是一种选择,因为这将"匹配"C#行为。

然而,当我试图像一样将模式嵌套在另一个模式中时,就会出现这个问题

String x =  "(?<InnerData>...)no group(?<InnerGroup>foo)";
String y = "(?<header>[...])some data" + x + "more regex" + x;
Pattern.compile(y);

其中x是在y中重复的内部内容,并且它不是我可以粘贴重复修饰符的东西。


我知道拥有相同名称的组是没有意义的,因为它怎么知道你想要什么?

所以,问题是——我该怎么办
使用Matcher.group(int)是我唯一的选择并放弃组名吗?

如果我至少正确理解了这个问题,那么使用regex就无法做到这一点。如果您能提供一些示例数据,那么这些数据将非常有用。

第一个

"(?<header>[...])some data" + x1 + "more regex" + x2

对于您的示例,只要x1x2是具有不同组名的同一正则表达式,这就可以工作。但我相信这不是你想要的。

第二次

假设字符串:FEW014 BKN025CB

我有三个我感兴趣的参数,比如说:

a可以是OVCFEWBKN

h可以是任意一组恰好为3位的

t可以是CBTCU或不存在

此外,这些参数的字符串可以具有这3个参数的多达4次出现;这个例子有2个,但是可以增加到4个。

现在假设regex(匹配这3个参数):

(?P<a>FEW|BKN|OVC)(?P<h>[d]{3})(?P<t>CB|TCU)?

我可以使用正则表达式引擎来获得这些参数的所有出现的列表,但引擎不会将它们相互关联。

我会得到如下的东西:

a:
FEW
BKN
h:
014
025
t:
CB

看看我是怎么忘记CB的来源的?这是预期的行为,因为正则表达式引擎不会保持状态。他们只是把东西塞进桶里。

最后

实现这一点的方法是,不要贪婪地使用正则表达式,只需匹配一次相关的东西,存储它们,然后继续。

--

我在那里使用的第二个例子是从一个真实世界的案例中偷来的,在这个案例中实现了这一点;只是为了简单起见更改了一些名称。

FEW014 BKN025CB是文本气象报告的一部分,以解释的方式进行解析。

希望它能帮助你理解这笔交易,以下是实现这一点的代码:

@occurs(4)
@search(r"""
(?P<amount>FEW|SCT|BKN|OVC)
(?P<height>[d]{3}|///)
(?P<type>CB|TCU|///)?
""")
def pclouds(item):
"""Returns ((amount, height, type),) of ((string, int, string),) for
clouds or ()"""
tcloud = namedtuple('Cloud', 'amount height type')
height = item['height']
if height == '///':
height = -1
else:
height = int(height)
return tcloud(item['amount'], height, item['type'])

https://github.com/pedro2555/avweather/blob/master/avweather/_metar_parsers.py#L221

  1. 搜索装饰器,搜索给定正则表达式的一个实例
  2. 出现装饰器,重复搜索给定次数
  3. 调用pclouds函数,注意item只保存一组3个值

为什么需要命名组?

我认为这对你的问题没有必要。它只找到与find的连续匹配在这种情况下,唯一的组是组1。

导入java.util.regex.Matcher;导入java.util.regex.Pattern;

public class Main
{
public static void main(String[] args) {
String patt = "\D+(\d+)";
String target = "abc123def456";
Pattern pattern = Pattern.compile(patt);
Matcher matcher = pattern.matcher(target);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
}
}

程序退出:

123
456

演示

最新更新