我正在尝试使用[ăâîșțĂÂÎȘȚ]
这样的正则表达式来匹配罗马尼亚字母变音符号(ISO 8859-16 / Windows-1250)。问题是正则表达式也会匹配a,i,s,t,A,I,S,T(上面提到的变音符号的拉丁字母对应字符)的正则表达式,我不想要这个。
由于性能时间的原因,我没有尝试逐个字符地比较字符串。
无论如何,我是否可以使正则表达式与这些字符完全匹配?
答案 0 :(得分:2)
如果你的正则表达式作为文字渲染文本存在,它已经被合并了 并且应该作为不同的代码点存在。
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=Combining_Diacritical_Marks}
一样的正则表达式
得到那些。
更新信息:
在寻找一个事实上的解决方案时,我遇到了这个Java信息
来自http://www.regular-expressions.info/unicode.html。
在Java中,正则表达式标记\ uFFFF仅匹配指定的标记 代码点,即使你打开规范等价。 但是,同样的语法\ uFFFF也用于插入 Unicode字符到Java源代码中的文字字符串 码。 Pattern.compile(“\ u00E0”)将匹配 à的单码点和双码点编码, 而Pattern.compile(“\ u00E0”)仅匹配 单码点版本。记得写的时候 正则表达式作为Java字符串文字,必须转义反斜杠。 前Java代码编译正则表达式à,而后者 编译\ u00E0。取决于你正在做什么, 差异可能很大。
因此,通过在类中输入二元文字,它看起来像Pattern.compile("[à]")
实际上会匹配
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
或
0000E0 à LATIN SMALL LETTER A WITH GRAVE
与您现在看到的 grave 无法匹配a
。
注意 - 如果您只使用“[\\ u00E0]”,则会错过a + grave
。
这是有效的。
答案 1 :(得分:0)
我相信这种情况正在发生,因为这些字符被视为两个Unicode代码点。我建议尝试使用类似\ uFFFF的语法专门匹配代码点,其中FFFF是代码点。确切的语法取决于您正在使用的正则表达式实现。
请记住,Unicode字符可以编码为单个代码点或多个,因此您需要考虑到这一点。示例:à编码为U + 0061 U + 0300以及U + 00E0。
我希望这有帮助!
答案 2 :(得分:0)
正如Unicode中已经提到的,有两种选择。
'\u0061' 'a' LATIN SMALL LETTER A
'\u0300' ̀ COMBINING GRAVE ACCENT
或
'\u00E0' 'à' LATIN SMALL LETTER A WITH GRAVE
有一个Normalizer
可以“规范化”为任何一种形式(并处理连字):
String regex = "(?u)[ăâîșțĂÂÎȘȚ]";
regex = Normalizer.normalize(regex, Form.NFC); // Composed form
Pattern pattern = Pattern.compile(regex);
使用“(?u)”或带有Pattern.compile并带有UNICODE标志的标志可能已经解决了该问题。但是,使用不带单独拉丁语('a'
)的Unicode变体肯定可以。
规范化器尤其应应用于搜索到的字符串。