我正在创建一个在控制台上请求某些名称的java应用程序,然后使用正则表达式来提取没有逗号的名称,并且仅根据此表达式提取正确的名称:
(\\w{2,}(|\\s\\w{2,})+)
我在web正则表达式模拟器上检查了上面的表达式,似乎可以正常工作,但是当我尝试使用Pattern和Matcher Classes在Java上匹配它时,它对于以下名称不起作用: Alvaro de拉托雷。
它将名称分为4组(在本例中)。我需要化合物名称只在一个字符串中。
我非常感谢任何帮助。提前谢谢。
答案 0 :(得分:2)
我假设您要从" Alvaro de la Torre" 中提取" de la Torre" 等字符串。
使用正则表达式,捕获组2将以+
重复,并且包含" de" 在第一次迭代中," la" 在第二次迭代中," Torre" 在第三次也是最后一次迭代。所以,当你最终从Matcher
获得第2组时,它只包含"托瑞" 强>
因此,您必须capture a repeated group:
,而不是重复捕获组"(\\w{2,}(|(\\s\\w{2,})+))"
请注意包含内部组和+
的其他组。
现在,当你从Matcher
获得第2组时,它包含内部组的所有重复,即" de la Torre" :
Pattern pattern = Pattern.compile("(\\w{2,}(|(\\s\\w{2,})+))");
Matcher matcher = pattern.matcher("Alvaro de la Torre");
matcher.matches();
System.out.println(matcher.group(2));
打印" de la Torre"
。
上述正则表达式的更好的等效版本是:
"\\w{2,}((?:\\s\\w{2,})*)"
然后得到第1组而不是第2组。将整个正则表达式包装在捕获组中是没有意义的,因为整个匹配只是默认组0。
如果您只想从较大的字符串中提取" Alvaro de la Torre" 等全名,请使用matcher.find()
代替{{1} },并获得匹配的子字符串matcher.matches()
(获取默认组0,即匹配)。在这种情况下,您也不需要任何明确的捕获组。
答案 1 :(得分:0)
由于我们生活在一个确定性的世界中,机器遵循确定性规则。特别是,在正则表达式中,如果满足捕获组的第一个字段,则解析器将不会检查第二个字段,如果它不是绝对必要的话。
因此,由于嵌套捕获组((|\\s\\w{2,})
)的第一个字段是空字符串,因此正则表达式对它感到满意,而不检查其他字段。这就是为什么它返回4个不同的结果而不是1的原因。
替代正则表达式是:
(\\w{2,}(\\s\\w{2,}|)+)
反转捕获组中2个字段的顺序。
等效的正则表达式是:
(\\w{2,}(\\s\\w{2,})*)
检查this demo vs this other one(由于突出原因,正则表达略有不同)。
答案 2 :(得分:0)
首先,您希望\w
匹配多个字母,而不是数字0-9
。所以像Jack is 23yrs old
这样的字符串是完全匹配的。
其次,你的分组中有一个管道,如果试图带来可选的含义并且不是偶然的,那么它不是展示这种质量的好方法。什么是正确的方法?使用明确包含可选功能的明星*
量词。
第三,\s
表示不仅仅是Space \x20个字符。它匹配标签\t
,换行符\n
,回车符\r
。所以像
My name is
Jack
也是一个完整的匹配。
最后,如果您只需要返回完整匹配的字符串,则根本不需要捕获组:
(?i)[a-z]{2,}(?:[ ][a-z]{2,})*