Java Regex不一致的组

时间:2015-03-31 16:56:52

标签: java regex string matcher regex-group

请参阅SO上的以下问题:

Java: Regex not matching

我的正则表达群体不一致。我的代码如下:

public class RegexTest {

    public static void main(String[] args) {

        // final String VALUES_REGEX = "^\\{([0-9a-zA-Z\\-\\_\\.]+)(?:,\\s*([0-9a-zA-Z\\-\\_\\.]*))*\\}$";
        final String VALUES_REGEX = "\\{([\\w.-]+)(?:, *([\\w.-]+))*\\}";

        final Pattern REGEX_PATTERN = Pattern.compile(VALUES_REGEX);
        final String values = "{df1_apx.fhh.irtrs.d.rrr, ffd1-afp.farr.d.rrr.asgd, ffd2-afp.farr.d.rrr.asgd}";
        final Matcher matcher = REGEX_PATTERN.matcher(values);
        if (null != values && matcher.matches()) {
            // for (int index=1; index<=matcher.groupCount(); ++index) {
            // System.out.println(matcher.group(index));
            // }

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

    }
}

我尝试了以下组合:

A)正则表达式为&#34; ^ \ {([0-9a-zA-Z \ - \ _ \。] +)(?:,\ s *([0-9a-zA-Z \ - \ _ \] )) \} $&#34。并使用groupCount()进行迭代。结果:

df1_apx.fhh.irtrs.d.rrr

ffd2-afp.farr.d.rrr.asgd

B)正则表达式为^ \ {([0-9a-zA-Z \ - \ _ \。] +)(?:,\ s *([0-9a-zA-Z \ - \ _ \。 ] )) \} $&#34;并使用matcher.find()。结果:没有结果。

C)正则表达式为&#34; \ {([\ w .-] +)(?:,([\ w .-] +)) \}&#34;并使用groupCount()进行迭代。结果:

df1_apx.fhh.irtrs.d.rrr

ffd2-afp.farr.d.rrr.asgd

D)正则表达式为&#34; \ {([\ w .-] +)(?:,([\ w .-] +)) \}&#34;并使用matcher.find()。结果:没有结果。

我永远不会得到一致的群体。这里的预期结果是:

df1_apx.fhh.irtrs.d.rrr

ffd1-afp.farr.d.rrr.asgd

ffd2-afp.farr.d.rrr.asgd

请让我知道,我怎样才能实现它。

2 个答案:

答案 0 :(得分:1)

(?<=[{,])\s*(.*?)(?=,|})

你可以简单地使用它并抓住捕获。参见演示。

https://regex101.com/r/sJ9gM7/33

当你有(#something)*时,只有最后一组被正则表达式引擎记住。你不会以这种方式获得所有组。

答案 1 :(得分:0)

问题在于你试图同时做两件事:

  • 您要验证字符串格式
  • 您想要提取每个项目(具有未知数量的项目)

因此,使用匹配方法是不可能的,因为当您重复相同的捕获组时,之前的捕获将被最后一次覆盖。

一种可能的方法是使用find方法获取每个项目并使用邻接锚\G来检查格式。 \G确保当前匹配立即跟随字符串的前一个或开头:

(?:\\G(?!\\A),\\s*|\\A\\{)([\\w.-]+)(}\\z)?

模式细节:

(?:                  # two possible begins:
    \\G(?!\\A),\\s*  # contiguous to a previous match
                     # (but not at the start of the string)
  |                  # OR
    \\A\\{           # the start of the string
)
([\\w.-]+)           # an item in the capture group 1
(}\\z)?              # the optional capture group 2 to check
                     # that the end of the string has been reached

因此,要从头到尾检查字符串的格式,您只需要测试最后一次匹配是否存在捕获组。