用于搜索单词并返回行中的最后一个字符的正则表达式。目前我有这个 -> "[a-z]$|[a-zA-Z]+"
文本是"many??? Woooooooooooords are"。
问题在于匹配了"are"而不是"e",第二个正则表达式模式优先级更高。我想要匹配"are"以及"e"。
有什么解决办法吗?
([a-zA-Z]+)|([a-zA-Z]+([a-zA-Z]))$
(?s)^(?=.*([a-z])$)|[a-zA-Z]+
请查看正则表达式演示
说明:
(?s)
- 打开DOTALL模式,以便.
可以匹配换行符^
- 字符串的开头(?=.*([a-z])$)
- 正向前瞻检查整个字符串并捕获最后一个字母。如果有尾随空格,请将其替换为(?=.*([a-z])\\s*$)
。注意,您可以使用\\p{Ll}
来匹配Unicode小写字母。|
- 或者...[a-zA-Z]+
- 1个或多个字母(实际上,您可以在Java中使用\\pL
代替此选项,以允许匹配Unicode字母)由于这是Java,您只需要检查第一组是否不为null
,如果不是,则得到了最后一个字母。如果第一组为null,则得到了一个单词。
String s = "many??? Woooooooooooords are";
Pattern pattern = Pattern.compile("(?s)^(?=.*([a-z])$)|[a-zA-Z]+");
Matcher matcher = pattern.matcher(s);
while (matcher.find()){
if (matcher.group(1) != null) {
System.out.println("Last letter: " + matcher.group(1));
}
else {
System.out.println("Word found: " + matcher.group(0));
}
}
查看 IDEONE演示
这个正则表达式比 @stribizhev 的快两倍:[a-zA-Z]+($(?<=[a-z]))?
尤其是在失败的情况下,本例中最后一个字符不是小写字母。
基准测试
失败(!= [a-z]$):
示例"many??? Woooooooooooords are in the Fountain of despaR
Regex1: [a-zA-Z]+($(?<=[a-z]))?
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 8
Elapsed Time: 0.68 s, 679.77 ms, 679771 µs
Regex2: ^(?s)(?=.*([a-z])$)|[a-zA-Z]+
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 8
Elapsed Time: 1.14 s, 1139.35 ms, 1139345 µs
成功(== [a-z]$):
示例"many??? Woooooooooooords are in the Fountain of despar
Regex1: [a-zA-Z]+($(?<=[a-z]))?
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 8
Elapsed Time: 0.68 s, 678.97 ms, 678965 µs
Regex2: ^(?s)(?=.*([a-z])$)|[a-zA-Z]+
Options: < none >
Completed iterations: 50 / 50 ( x 1000 )
Matches found per iteration: 9
Elapsed Time: 0.72 s, 717.28 ms, 717276 µs
^(?=.*([a-z])$)|[a-zA-Z]+
来实现,但是需要些代码来正确提取文本内容。主要问题在于正则表达式无法多次消耗文本。你只能捕获重叠的文本,并且可能需要在前瞻中进行操作。 - Wiktor Stribiżew[a-zA-Z]*([a-zA-Z])
。全局查找中的最后一个匹配项将包含最后一个单词中的最后一个字母。您无法区分小写字母,并且将$
eos 标记与其一起添加不适用于其他[a-zA-Z]
。如果需要首先获取最后一个字符,请将其拆分为两个正则表达式。 - user557597