在句子中匹配最后一个字母以及单词的正则表达式

3

用于搜索单词并返回行中的最后一个字符的正则表达式。目前我有这个 -> "[a-z]$|[a-zA-Z]+"

文本是"many??? Woooooooooooords are"。

问题在于匹配了"are"而不是"e",第二个正则表达式模式优先级更高。我想要匹配"are"以及"e"。

有什么解决办法吗?


1
你可以使用^(?=.*([a-z])$)|[a-zA-Z]+来实现,但是需要些代码来正确提取文本内容。主要问题在于正则表达式无法多次消耗文本。你只能捕获重叠的文本,并且可能需要在前瞻中进行操作。 - Wiktor Stribiżew
@Deven:你在使用什么编程语言?如果你打算使用一个模式来获取想要的内容,我猜我的正则表达式应该是最好的选择。但从捕获组中提取值可能对你来说有些棘手。 - Wiktor Stribiżew
我假设你想找到所有的单词,如果它恰好是行中的最后一个单词,也要将其一起抓取。但是,最后一个单词不会首先匹配。只需使用 [a-zA-Z]*([a-zA-Z])。全局查找中的最后一个匹配项将包含最后一个单词中的最后一个字母。您无法区分小写字母,并且将 $ eos 标记与其一起添加不适用于其他 [a-zA-Z]。如果需要首先获取最后一个字符,请将其拆分为两个正则表达式。 - user557597
@stribizhev:你是对的,你的答案在这里是最有帮助的。其他答案中的单词没有与句子中的其他单词匹配,只有“are”匹配了。我还想匹配标点符号以找到句子数量,所以我想出了这个正则表达式。但现在Java代码似乎返回了空字符,尽管正则表达式是正确的。需要更多的工作…… - Deven
如果需要Java方面的帮助,我可以提供帮助。 - Wiktor Stribiżew
我为Java添加了自己的答案。 - Wiktor Stribiżew
5个回答

1
使用捕获组:
([a-zA-Z]+([a-z]))$

请参见正则表达式演示

对于文本many??? Woooooooooooords areare被捕获在第一组中,e被捕获在第二组中。


1
你可以使用这个:
([a-zA-Z]+)|([a-zA-Z]+([a-zA-Z]))$

这将捕获文本中所有单词及其最后一个字母。您需要在正则表达式中使用“g”修饰符(全局)。

1
主要问题是正则表达式无法多次消耗文本。你只能捕获重叠的文本,并且可以在环视内完成。因此,你可以使用:
(?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演示


1
至少在.NET、Java、Javascript和PHP中(因此似乎是一个标准),Group[0]包含所有匹配本身,因此您只需要对正则表达式中的最后一个字母进行分组。
[a-zA-Z]+([a-zA-Z])$
"many??? Woooooooooooords are"
您的文本将会像这样:
group[0] = "are"
group[1] = "e"

0

这个正则表达式比 @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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接