Java的Matcher.group(int)方法如何避免匹配括号内子大括号的内容

How does Java's Matcher.group (int) method avoid match the contents of sub-braces inside parentheses

我有一个像

这样的字符串
String str = "美国临时申请No.62004615";

还有一个像

这样的正则表达式
String regex = "(((美国|PCT|加拿大){0,1})([\u4E00-\u9FA5]{1,8})((NO.|NOS.){1})([\d]{5,}))";

其他代码为

 Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    while (matcher.find()) {
        System.out.println("1:"+matcher.group(1)+"\n"
                +"2:"+matcher.group(2)+"\n"
                +"3:"+matcher.group(3)+"\n"
                +"4:"+matcher.group(4)+"\n"
                +"5:"+matcher.group(5)+"\n"
                +"6:"+matcher.group(6)+"\n"
                +"7:"+matcher.group(7));
    }

我知道括号 () 用于启用正则表达式短语的分组。第1组是大组。

第二组是((美国|PCT|加拿大){0,1})匹配“美国”或"PCT"或“加拿大”。

第三组为([\u4E00-\u9FA5]{1,8})匹配长度为一到八的汉字

第四组是 ((NO.|NOS.){1}) 来匹配 NO.或 NOS。 第五组为([\d]{5,})匹配数

但是控制台是

1:美国临时申请No.62004615 2:美国 3:美国 4:临时申请 5:No. 6:No. 7:62004615

第(2)组与第(3)组相同。第(5)组与第(6)组相同

似乎组(3)再次重新匹配括号内的子括号。请问有没有办法只匹配最外层的括号。

理想的结果应该是

1:美国临时申请No.62004615 2:美国  3:临时申请 4:No. 5:62004615

听起来您想要一个 非捕获 组。来自 the Pattern documentation:

(?:X)        X, as a non-capturing group

所以,改变这个:

(美国|PCT|加拿大)

对此:

(?:美国|PCT|加拿大)

...然后在Matcher中根本不会表示为一个组。

一些旁注:

  • {0,1}等同于写?.
  • {1} 什么都不做,可以完全删除。
  • [\d]\d.
  • 相同