重复捕获组只匹配最后一次出现
Repetative capturing group matches only last occurence
鉴于我遇到奇怪的捕获组行为,请注意以下文本数据。
当我尝试仅遍历所有 table 的最后一行数据时。有没有办法维护所有捕获组而不仅仅是最后一行(每个 table 的值)?
我正在使用这个模式(?<tabname>\S+)\n\=*\n(?:(\d+)\ *\|\ *(\d+)\n)+
TABLE1
=======
1 | 2
15 | 2
3 | 15
TABLE2
=======
3 | 5
12 | 2
17 | 7
编辑:抱歉我的问题不一致,这里是我的预期和实际输出:
预期 输出为:
第 1 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 1
Group 3: 2
Group 4: 15
Group 5: 2
Group 6: 3
Group 7: 15
第 2 场比赛,共 2 场比赛:
Group "tabname": TABLE2
Group 2: 3
Group 3: 5
Group 4: 12
Group 5: 2
Group 6: 17
Group 7: 7
但是实际输出是:
第 1 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 3
Group 3: 15
第 2 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 17
Group 3: 7
我相信你可以使用这个正则表达式
(?s)(?:(TABLE\d+)|\G)(?:(?!TABLE).)+?(\d+)\s+\|\s+(\d+)
在 Java 的帮助下,您可以获得结果
String line = "TABLE1\n=======\n1 | 2\n15 | 2\n3 | 15\n\nTABLE2\n=======\n3 | 5\n12 | 2\n17 | 7";
String pattern = "(?s)(?:(TABLE\d+)|\G)(?:(?!TABLE).)+?(\d+)\s+\|\s+(\d+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
int flag = 0;
while (m.find()) {
if (m.group(1) != null) {
flag = 0;
}
if (flag == 0) {
System.out.println(m.group(1) + "\n" + m.group(2) + "\n" + m.group(3));
flag = 1;
} else {
System.out.println(m.group(2) + "\n" + m.group(3));
}
}
您可以分 2 次收集您的数据。第一个正则表达式将只匹配具有所有值的表:
"(?<tabledata>\S+)\s+\S+(?<vals>[|\d\s]+)"
参见 demo。接下来,我们将匹配数字并将它们添加到字符串数组(使用简单的 \d+
正则表达式)。
这是一个 full Java demo 产生 [[TABLE1, 1, 2, 15, 2, 3, 15], [TABLE2, 3, 5, 12, 2, 17, 7]]
:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
String s = "TABLE1\n=======\n1 | 2\n15 | 2\n3 | 15\n\nTABLE2\n=======\n3 | 5\n12 | 2\n17 | 7";
Pattern pattern = Pattern.compile("(?<tabledata>\S+)\s+\S+(?<vals>[|\d\s]+)");
Matcher matcher = pattern.matcher(s);
List<List<String>> res = new ArrayList<>();
while (matcher.find()){
List<String> lst = new ArrayList<>();
if (matcher.group("tabledata") != null) {
lst.add(matcher.group("tabledata"));
}
if (matcher.group("vals") != null) {
Matcher m = Pattern.compile("\d+").matcher(matcher.group("vals"));
while (m.find()) {
lst.add(m.group(0));
}
}
res.add(lst);
}
System.out.println(res);
}
}
鉴于我遇到奇怪的捕获组行为,请注意以下文本数据。 当我尝试仅遍历所有 table 的最后一行数据时。有没有办法维护所有捕获组而不仅仅是最后一行(每个 table 的值)?
我正在使用这个模式(?<tabname>\S+)\n\=*\n(?:(\d+)\ *\|\ *(\d+)\n)+
TABLE1
=======
1 | 2
15 | 2
3 | 15
TABLE2
=======
3 | 5
12 | 2
17 | 7
编辑:抱歉我的问题不一致,这里是我的预期和实际输出:
预期 输出为:
第 1 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 1
Group 3: 2
Group 4: 15
Group 5: 2
Group 6: 3
Group 7: 15
第 2 场比赛,共 2 场比赛:
Group "tabname": TABLE2
Group 2: 3
Group 3: 5
Group 4: 12
Group 5: 2
Group 6: 17
Group 7: 7
但是实际输出是:
第 1 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 3
Group 3: 15
第 2 场比赛,共 2 场比赛:
Group "tabname": TABLE1
Group 2: 17
Group 3: 7
我相信你可以使用这个正则表达式
(?s)(?:(TABLE\d+)|\G)(?:(?!TABLE).)+?(\d+)\s+\|\s+(\d+)
在 Java 的帮助下,您可以获得结果
String line = "TABLE1\n=======\n1 | 2\n15 | 2\n3 | 15\n\nTABLE2\n=======\n3 | 5\n12 | 2\n17 | 7";
String pattern = "(?s)(?:(TABLE\d+)|\G)(?:(?!TABLE).)+?(\d+)\s+\|\s+(\d+)";
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(line);
int flag = 0;
while (m.find()) {
if (m.group(1) != null) {
flag = 0;
}
if (flag == 0) {
System.out.println(m.group(1) + "\n" + m.group(2) + "\n" + m.group(3));
flag = 1;
} else {
System.out.println(m.group(2) + "\n" + m.group(3));
}
}
您可以分 2 次收集您的数据。第一个正则表达式将只匹配具有所有值的表:
"(?<tabledata>\S+)\s+\S+(?<vals>[|\d\s]+)"
参见 demo。接下来,我们将匹配数字并将它们添加到字符串数组(使用简单的 \d+
正则表达式)。
这是一个 full Java demo 产生 [[TABLE1, 1, 2, 15, 2, 3, 15], [TABLE2, 3, 5, 12, 2, 17, 7]]
:
import java.util.*;
import java.lang.*;
import java.io.*;
import java.util.regex.*;
class Ideone
{
public static void main (String[] args) throws java.lang.Exception
{
String s = "TABLE1\n=======\n1 | 2\n15 | 2\n3 | 15\n\nTABLE2\n=======\n3 | 5\n12 | 2\n17 | 7";
Pattern pattern = Pattern.compile("(?<tabledata>\S+)\s+\S+(?<vals>[|\d\s]+)");
Matcher matcher = pattern.matcher(s);
List<List<String>> res = new ArrayList<>();
while (matcher.find()){
List<String> lst = new ArrayList<>();
if (matcher.group("tabledata") != null) {
lst.add(matcher.group("tabledata"));
}
if (matcher.group("vals") != null) {
Matcher m = Pattern.compile("\d+").matcher(matcher.group("vals"));
while (m.find()) {
lst.add(m.group(0));
}
}
res.add(lst);
}
System.out.println(res);
}
}