如何用单个正则表达式匹配重复子模式提取所有侄女的姓名与年龄
问题描述
我有如下字符串:
String sentence = "My nieces are Cara:8 Sarah:9 Tara:10";
我希望提取所有侄女的姓名和年龄,尝试使用了以下正则匹配器:
String regex = "My\\s+nieces\\s+are((\\s+(\\S+):(\\d+))*)"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(sentence);
我发现执行类似下面的代码:
matcher.find(0); // 重置匹配指针 String niece = matcher.group(2); String nieceName = matcher.group(3); String nieceAge = matcher.group(4);
只会返回最后一个侄女的信息(" Tara:10"、"Tara"、"10")。请问如何仅使用一个正则表达式/模式收集所有侄女的信息,同时避免使用字符串拆分(split)方法?
解决方案
核心原因说明
你原方法只返回最后一个结果的原因是:正则中的((\s+(\S+):(\d+))*)属于重复捕获组,Java正则引擎在处理这类重复组时,只会保留最后一次匹配的内容,因此对应的分组只会存储最后一个侄女的信息。
可行实现方式
方式一:验证前缀后循环提取单个条目
先验证字符串前缀符合预期,再逐个匹配姓名:年龄的条目:
String sentence = "My nieces are Cara:8 Sarah:9 Tara:10"; // 正则同时匹配前缀和单个侄女条目,用分组区分 Pattern pattern = Pattern.compile("My\\s+nieces\\s+are|(\\S+):(\\d+)"); Matcher matcher = pattern.matcher(sentence); // 先匹配并跳过前缀部分 if (matcher.find()) { // 循环提取所有侄女信息 while (matcher.find()) { String name = matcher.group(1); String age = matcher.group(2); System.out.printf("姓名:%s,年龄:%s%n", name, age); } }
方式二:直接匹配所有姓名:年龄条目
如果不需要严格验证前缀,可直接匹配符合格式的条目:
String sentence = "My nieces are Cara:8 Sarah:9 Tara:10"; // 匹配以空白开头的姓名:年龄,捕获姓名和年龄 Pattern pattern = Pattern.compile("\\s+(\\S+):(\\d+)"); Matcher matcher = pattern.matcher(sentence); while (matcher.find()) { String name = matcher.group(1); String age = matcher.group(2); System.out.printf("姓名:%s,年龄:%s%n", name, age); }
方式三:使用命名捕获组(增强可读性)
如果想让代码更易读,可以使用命名捕获组:
String sentence = "My nieces are Cara:8 Sarah:9 Tara:10"; Pattern pattern = Pattern.compile("\\s+(?<name>\\S+):(?<age>\\d+)"); Matcher matcher = pattern.matcher(sentence); while (matcher.find()) { String name = matcher.group("name"); String age = matcher.group("age"); System.out.printf("姓名:%s,年龄:%s%n", name, age); }
内容的提问来源于stack exchange,提问作者Chad Chaddington
相关产品推荐
相关产品推荐

