
在实际开发中,我们经常需要从非结构化或半结构化的文本数据中提取特定的信息。例如,给定以下格式的字符串数据,其中包含多个以#section开头的条目:
#Section250342,Main,First/HS/12345/Jack/M,200010 10.00 200011 -2.00, #Section250322,Main,First/HS/12345/Aaron/N,200010 17.00, #Section250399,Main,First/HS/12345/Jimmy/N,200010 12.00, #Section251234,Main,First/HS/12345/Jack/M,200011 11.00
我们的目标是,针对所有包含/Jack/M的行,提取以下三类数据:
值得注意的是,日期和数值总是成对出现,且每行可能包含一个或多个这样的日期-数值对。直接使用单一正则表达式一次性捕获所有三组数据,尤其是在日期-数值对数量不定的情况下,会变得非常复杂且容易出错。
为了有效地解决这个问题,我们采用一种两阶段策略:
我们将使用以下正则表达式:
立即学习“Java免费学习笔记(深入)”;
#Section(d+)(?:(?!#Sectiond).)*Jack/M,(d+h+[-+]?d+(?:.d+)?(?:s+d+h+[-+]?d+(?:.d+)?)*)
下面对该正则表达式的各个部分进行详细解释:
通过这个正则表达式,我们能得到两个主要的捕获组:
在Java中,我们将使用java.util.regex.Pattern和java.util.regex.Matcher类来执行正则表达式匹配。然后,我们将对捕获到的第二个组进行字符串分割和逻辑分组。
示例代码:逐个匹配结果输出
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class DataExtractor {
public static void main(String[] args) {
String regex = "#Section(\d+)\b(?:(?!#Section\d).)*\bJack/M,(\d+\h+[-+]?\d+(?:\.\d+)?(?:\s+\d+\h+[-+]?\d+(?:\.\d+)?)*)";
String string = "#Section250342,Main,First/HS/12345/Jack/M,200010 10.00 200011 -2.00,
"
+ "#Section250322,Main,First/HS/12345/Aaron/N,200010 17.00,
"
+ "#Section250399,Main,First/HS/12345/Jimmy/N,200010 12.00,
"
+ "#Section251234,Main,First/HS/12345/Jack/M,200011 11.00";
// 编译正则表达式,使用MULTILINE模式以正确处理多行输入
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);
System.out.println("--- 逐个匹配结果 ---");
while (matcher.find()) {
List<String> dates = new ArrayList<>();
List<String> values = new ArrayList<>();
// 捕获组1:段落编号
System.out.println("Group 1 (Section ID): " + matcher.group(1));
// 捕获组2:所有日期和数值的字符串
String[] parts = matcher.group(2).split("\s+"); // 按一个或多个空格分割
for (int i = 0; i < parts.length; i++) {
if (i % 2 == 0) { // 偶数索引是日期
dates.add(parts[i]);
} else { // 奇数索引是数值
values.add(parts[i]);
}
}
System.out.println("Group 2 (Dates): " + Arrays.toString(dates.toArray()));
System.out.println("Group 3 (Values): " + Arrays.toString(values.toArray()));
}
}
}输出结果:
--- 逐个匹配结果 --- Group 1 (Section ID): 250342 Group 2 (Dates): [200010, 200011] Group 3 (Values): [10.00, -2.00] Group 1 (Section ID): 251234 Group 2 (Dates): [200011] Group 3 (Values): [11.00]
示例代码:聚合所有匹配结果输出
如果需要将所有匹配到的数据聚合到各自的列表中,并在循环结束后统一输出,可以修改代码如下:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class AggregatedDataExtractor {
public static void main(String[] args) {
String regex = "#Section(\d+)\b(?:(?!#Section\d).)*\bJack/M,(\d+\h+[-+]?\d+(?:u002e\d+)?(?:\s+\d+\h+[-+]?\d+(?:u002e\d+)?)*)";
String string = "#Section250342,Main,First/HS/12345/Jack/M,200010 10.00 200011 -2.00,
"
+ "#Section250322,Main,First/HS/12345/Aaron/N,200010 17.00,
"
+ "#Section250399,Main,First/HS/12345/Jimmy/N,200010 12.00,
"
+ "#Section251234,Main,First/HS/12345/Jack/M,200011 11.00";
Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
Matcher matcher = pattern.matcher(string);
List<String> allSectionIds = new ArrayList<>();
List<String> allDates = new ArrayList<>();
List<String> allValues = new ArrayList<>();
while (matcher.find()) {
allSectionIds.add(matcher.group(1)); // 添加段落编号
String[] parts = matcher.group(2).split("\s+");
for (int i = 0; i < parts.length; i++) {
if (i % 2 == 0) {
allDates.add(parts[i]); // 添加日期
} else {
allValues.add(parts[i]); // 添加数值
}
}
}
System.out.println("--- 聚合所有匹配结果 ---");
System.out.println("All Section IDs: " + Arrays.toString(allSectionIds.toArray()));
System.out.println("All Dates: " + Arrays.toString(allDates.toArray()));
System.out.println("All Values: " + Arrays.toString(allValues.toArray()));
}
}输出结果:
--- 聚合所有匹配结果 --- All Section IDs: [250342, 251234] All Dates: [200010, 200011, 200011] All Values: [10.00, -2.00, 11.00]
通过上述方法,我们不仅成功地从复杂字符串中提取了所需的三组数据,而且还优雅地解决了日期-数值对数量不定的挑战,展示了正则表达式和Java编程在数据处理中的强大协同作用。
以上就是复杂字符串数据解析:正则表达式与Java后处理实战的详细内容,更多请关注php中文网其它相关文章!
每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。
Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号