Java正则表达式匹配拉丁对应字符的变音符号

Java正则表达式匹配拉丁对应字符的变音符号,java,regex,nlp,diacritics,Java,Regex,Nlp,Diacritics,我正在尝试使用一个正则表达式,比如[编码],来匹配罗马尼亚字母的发音(ISO 8859-16/Windows-1250)。问题是正则表达式也会匹配a,i,s,t,a,i,s,t的正则表达式(上面提到的变音符号对应的拉丁字母),我不希望这样。 由于性能问题,我没有尝试逐个字符比较字符串 我是否可以让正则表达式与这些字符完全匹配?我认为这是因为这些字符被视为两个Unicode代码点。我建议尝试使用\uFFFF这样的语法专门匹配代码点,其中FFFF是代码点。确切的语法将取决于您使用的正则表达式实现 请

我正在尝试使用一个正则表达式,比如
[编码]
,来匹配罗马尼亚字母的发音(ISO 8859-16/Windows-1250)。问题是正则表达式也会匹配a,i,s,t,a,i,s,t的正则表达式(上面提到的变音符号对应的拉丁字母),我不希望这样。 由于性能问题,我没有尝试逐个字符比较字符串


我是否可以让正则表达式与这些字符完全匹配?

我认为这是因为这些字符被视为两个Unicode代码点。我建议尝试使用\uFFFF这样的语法专门匹配代码点,其中FFFF是代码点。确切的语法将取决于您使用的正则表达式实现

请记住,Unicode字符可以编码为单个代码点,也可以编码为多个代码点,因此您需要考虑这一点。示例:编码为U+0061 U+0300和U+00E0的a


我希望这有帮助

如果您的正则表达式作为文本呈现文本存在,则它已被组合
并且应该作为不同的代码点存在

000074    t    LATIN SMALL LETTER T
+
000326    ̦    COMBINING COMMA BELOW
=
00021B    ț    LATIN SMALL LETTER T WITH COMMA BELOW
以防万一,您应该使用十六进制代码点来表示它们,即。
u\021B

Java引擎是否可能正在从正则表达式中剥离组合字符?
x21B在哪里变成x74?可能是这样

同时,如果您希望源中的字母不会呈现,则可以
使用类似正则表达式的
\p{Script=Latin}\p{Block=combing_Diacritical_Marks}

去拿那些

更新信息:
在搜索实际解决方案时,我发现了以下Java信息

在Java中,regex标记\uFFFF仅与指定的 代码点,即使启用了规范等价性。 但是,同样的语法\uFFFF也用于插入 在Java源代码中将Unicode字符转换为文字字符串 代码。Pattern.compile(“\u00E0”)将与 a的单码点和双码点编码, 而Pattern.compile(“\u00E0”)只与 单代码点版本。记住,当你写一篇文章的时候 正则表达式作为Java字符串文本,必须转义反斜杠。 前一个Java代码编译正则表达式,而后一个代码编译正则表达式 编译\u00E0。取决于你在做什么 差异可能很大

因此,通过在类中输入对偶文本,它看起来像是
Pattern.compile(“[a]”)

实际上会匹配

000061    a    LATIN SMALL LETTER A
or
000300    ̀    COMBINING GRAVE ACCENT
or
0000E0    à    LATIN SMALL LETTER A WITH GRAVE  
在类中放置代理项对时,也会出现同样的问题。
有一个解决办法

避免在类中输入这些文本。
相反,将它们作为一系列的替代品
(?:á| | | | |)

这样做会迫使它匹配

000061    a    LATIN SMALL LETTER A
000300    ̀    COMBINING GRAVE ACCENT

它不会像你现在看到的那样与独立于坟墓的
a
相匹配

注意-如果只使用“[\\u00E0]”,您将错过
a+grave


这是有效的。

正如Unicode中已经提到的,有两种选择

'\u0061'    'a'   LATIN SMALL LETTER A
'\u0300'     ̀     COMBINING GRAVE ACCENT

有一种方法可以“规范化”为任何一种形式(并处理连字):

使用“(?u)”或带有Pattern.compile with UNICODE标志的标志可能已经解决了这个问题。但是使用不带单独拉丁语(
'a'
)的Unicode变体肯定可以


规范化器应该特别应用于搜索的字符串。

您使用的是什么正则表达式引擎/语言?这不应该发生,看,这是事实。您能提供一个Java演示来展示您所描述的行为吗?编辑器可以通过多种方式写出这样的字符,因此可以按照您的建议使用unicode转义序列,以及对输入字符串进行规范化(请参阅Normaliser和教程)在相同逻辑字符串的不同编码之间保证一致的行为可能是明智的。
'\u0061'    'a'   LATIN SMALL LETTER A
'\u0300'     ̀     COMBINING GRAVE ACCENT
'\u00E0'    'à'   LATIN SMALL LETTER A WITH GRAVE  
String regex = "(?u)[ăâîșțĂÂÎȘȚ]";
regex = Normalizer.normalize(regex, Form.NFC); // Composed form
Pattern pattern = Pattern.compile(regex);