-3

我正在尝试Pattern从字符串中获取数字。

包含我的数字的字符串如下所示:

{1,3}{4,5}...{6,7}

我的输出应该是:

1 3
4 5
...
6 7 

代码:

private static void products(final String products) {
    final String regex = "(\\{([0-9]+),([0-9]+)\\})+";


    final java.util.regex.Pattern p = java.util.regex.Pattern.compile(regex);

    final Matcher matcher = p.matcher(products);
    if(!matcher.matches()) {
        throw new IllegalArgumentException("Wrong semantic of products!");
    }

    while(matcher.find()) {
        System.out.print(matcher.group(1) + " ");
        System.out.println(matcher.group(2));
    }
}

我遇到的问题是对上述函数的调用不会打印出任何内容。我将如何解决这个问题?

4

3 回答 3

3

你需要+在最后取出,因为你想一次提取一个。

整个事情都在括号中,这将是第 1 组,或者使其成为不匹配的组(带有?:)或从 2 开始。删除括号将不起作用,因为+在以下正则表达式中添加了(参见代码)。

matcher.matches检查整个字符串,如果没有 regex,它将无法与 regex 一起使用+,您可能仍然需要原始的 regex。

此外,使用matchesand thenfindMatcher不起作用,因为matches将移动字符串中的当前位置,因此,如果匹配,它将位于字符串的末尾。因此find将永远找不到任何东西,因为没有字符串可供搜索。您可以使用resetonMatcher来重置其位置,但这显然不能解决上述问题。

更新代码:

private static void products(final String products) {
    final String regex = "(?:\\{([0-9]+),([0-9]+)\\})";

    // validation
    final Pattern pAll = Pattern.compile(regex + "+");

    if (!pAll.matcher(products).matches()) {
        throw new IllegalArgumentException("Wrong semantic of products!");
    }

    // extraction
    final Pattern p = Pattern.compile(regex);
    final Matcher matcher = p.matcher(products);

    while (matcher.find()) {
        System.out.print(matcher.group(1) + " ");
        System.out.println(matcher.group(2));
    }
}

测试

对于任何有兴趣的人,这是一种在 1 遍中完成的方法:(matches遍历整个字符串,从而导致 2 遍通过字符串)

private static void products(final String products) {
    final String regex = "\\{([0-9]+),([0-9]+)\\}";

    final Pattern p = Pattern.compile(regex);

    final Matcher matcher = p.matcher(products);
    int lastEnd = 0;
    while (matcher.find()) {
        if (lastEnd != matcher.start())
           throw new IllegalArgumentException("Wrong semantic of products!");
        System.out.print(matcher.group(1) + " ");
        System.out.println(matcher.group(2));
        lastEnd = matcher.end();
    }
    if (lastEnd != products.length())
        throw new IllegalArgumentException("Wrong semantic of products!");
}

唯一的缺点是它会在找到无效数据之前打印出所有值。

例如,products("{1,3}{4,5}a{6,7}");将打印出:

1 3
4 5

在抛出异常之前(因为直到那里字符串才有效)。

于 2013-05-16T08:04:10.890 回答
2

另一种解决方案:

private static void products2(final String products) {
    final String regex = "\\{([0-9]+),([0-9]+)\\}";

    if (products.split(regex).length > 0) {
        throw new IllegalArgumentException("Wrong semantic of products!");
    }

    final Matcher matcher = Pattern.compile(regex).matcher(products);
    while (matcher.find()) {
        System.out.print(matcher.group(1) + " ");
        System.out.println(matcher.group(2));
    }
}

这个可能效率较低(String.split(...))但可能更优雅(将验证与处理分开)。

于 2013-05-16T09:53:52.850 回答
0

另一种解决方案是将字符串拆分为“}”,然后遍历结果数组并提取数字。每个数组元素应匹配 "\\{(\\d+),(\\d+)"

于 2013-05-16T09:47:24.487 回答