修改 Java 正则表达式以查找匹配项之前的单词

问题描述 投票:0回答:1

正则表达式

\b(\w*)[[à-ü]|[À-Ü]]\b
查找以西班牙语波浪号(又名重音符号)结尾的单词。例如,在“Tengo algún Cafe”中,它匹配
algún
café

我想修改它,以便它捕获当前匹配项前面的单词。例如,在“El mandatario celebró en sus redes”中,它应该匹配

mandatario
。我对此正则表达式的 Java 实现特别感兴趣。

我尝试使用捕获组如下:

        Pattern pattern = Pattern.compile("\\b( \\w* )[[à-ü]|[À-Ü]]\\b");

然后提取

String precedingWord = matcher.group(1);
。然而,这并没有奏效。

java regex
1个回答
0
投票

例如,在“Tengo algún咖啡馆”中,它匹配algún和café。

不,没有。该正则表达式有太多错误,从哪里开始?

这不是
\b
的意思

\b
在基本模式下是 ascii 绑定的。所以,你会发现这种疯狂:

Pattern p = Pattern.compile("\\balgú\\b");
System.out.println(p.matcher("algún").find());

这会打印...

true
。这是疯狂的,因为它应该打印
false
。毕竟,我们的输入字符串中的
ú
之后没有“断词”。事实上,用普通的旧 ascii
u
替换它,你就会得到预期的
false

Pattern 类中对此的记录很差。正在发生的事情是,模式类试图与过时的仅 ascii 概念兼容,尽管 java 完全不是那样。因此,ú 被视为“不是单词字符”,因为它不在 a-z 范围内。我们需要告诉正则表达式不要做愚蠢的事情,我们用

(?U)
来打开“unicode 模式”。那么一切都好:

Pattern p = Pattern.compile("(?U)\\balgú\\b");
System.out.println(p.matcher("algún").find());

好吧,最后,

false
。这就是一个开始。

您忘记了带重音的字母之后的字母

你需要在里面塞另一个

\w*
。而且你不需要括号。

这不是角色类的工作方式

这个:

[[à-ü]|[À-Ü]]

是官样文章。在

[]
内,大多数标准正则表达式规则都不适用。
-
具有特殊含义,除非它位于开头或结尾(在
[]
之外不正确,其中
-
仅表示
-
)。
.
仅表示点(在
[]
之外表示“任何字符”),
+
仅表示+等等。特别是
|
只是表示 bar:

Pattern p = Pattern.compile("H[e|a]llo");
System.out.println(p.matcher("Hello").matches());
System.out.println(p.matcher("Hallo").matches());
System.out.println(p.matcher("H|llo").matches());

打印

true
... 3 次。并集(如“a 或 b”)在字符类中自动发生,如果需要交集,则需要
&&
(在 char 类中的特殊含义)。所以,你只想:

[à-üÀ-Ü]

除非你不想要那样。 unicode表中à和ü之间有一堆字符。例如,÷ 和 ø。当然 ÷ 不是您想要捕获的内容。最好明确地将它们全部列出来。

查找带有西班牙语波浪号(又名重音符号)的单词

好吧,那么,那就只是

ñ
然后:将
[à-ü]|[À-Ü]]
替换为
ñ
。或者,如果您确实想捕获 ú,例如
[ñúíáé]
- 将它们列出来。依赖 unicode 范围是自找麻烦。可能会出现一些问题,例如您无意中意外包含 ÷,并且正则表达式不建议这样做。

不要重新列出大写变体

您可以使用

(?i)
标志来打开不区分大小写模式。

让我们回顾一下

我们在:

Pattern p = Pattern.compile("(?Ui)\\b\\w*[ñáúíé]\\w*\\b");

它将匹配任何包含至少一个重音字符的单词。

现在..匹配它之前的单词

您为此使用正向前瞻:

Pattern p = Pattern.compile("(?Ui)\\b\\w+\\b(?=\\s+\\w*[ñáúíé]\\w*\\b)");
Matcher m = p.matcher("Tengo algún café");
while (m.find()) System.out.println("Found: " + m.group(0));

注意包含

\\s+
- 我们需要在某处消耗 Tengo 和 algún 之间的空间。正向前瞻要求括号中的内容存在,但不会消耗它。

© www.soinside.com 2019 - 2024. All rights reserved.