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);