你需要+
在最后取出,因为你想一次提取一个。
整个事情都在括号中,这将是第 1 组,或者使其成为不匹配的组(带有?:
)或从 2 开始。删除括号将不起作用,因为+
在以下正则表达式中添加了(参见代码)。
matcher.matches
检查整个字符串,如果没有 regex,它将无法与 regex 一起使用+
,您可能仍然需要原始的 regex。
此外,使用matches
and thenfind
将Matcher
不起作用,因为matches
将移动字符串中的当前位置,因此,如果匹配,它将位于字符串的末尾。因此find
将永远找不到任何东西,因为没有字符串可供搜索。您可以使用reset
onMatcher
来重置其位置,但这显然不能解决上述问题。
更新代码:
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
在抛出异常之前(因为直到那里字符串才有效)。