正则表达式:什么是InCombiningDiacriticalMarks?

mar*_*pes 80 java regex unicode

以下代码是众所周知的将重音字符转换为纯文本:

Normalizer.normalize(text, Normalizer.Form.NFD).replaceAll("\\p{InCombiningDiacriticalMarks}+", "");
Run Code Online (Sandbox Code Playgroud)

我用这个替换了我的"手工制作"方法,但我需要理解replaceAll的"正则表达式"部分

1)什么是"InCombiningDiacriticalMarks"?
2)文件在哪里?(和类似的?)

谢谢.

tch*_*ist 68

\p{InCombiningDiacriticalMarks}是一个Unicode块属性.在JDK7中,您将能够使用两部分表示法编写它\p{Block=CombiningDiacriticalMarks},这对读者来说可能更清晰.据记载这里UAX#44:"Unicode字符数据库".

这意味着代码点落在一个特定的范围内,一个块,已被分配用于该名称的东西.这是一种糟糕的方法,因为不能保证该范围内的代码点是或不是任何特定的东西,也不保证该块外的代码点本质上不是相同的字符.

例如,\p{Latin_1_Supplement}块中有拉丁字母,如é,U + 00E9.但是,有些东西也不是拉丁字母.当然,到处都有拉丁字母.

块几乎不是你想要的.

在这种情况下,我怀疑你可能想要使用该属性\p{Mn},也就是说\p{Nonspacing_Mark}.Combining_Diacriticals块中的所有代码点都属于这种类型.还有(从Unicode 6.0.0开始)1087 Nonspacing_Marks 不在该块中.

这与检查几乎相同\p{Bidi_Class=Nonspacing_Mark},但并不完全相同,因为该组还包括封闭标记\p{Me}.如果你想要两者,你可以说[\p{Mn}\p{Me}]你是否使用默认的Java正则表达式引擎,因为它只能访问General_Category属性.

您必须使用JNI以像Google那样的方式访问ICU C++正则表达式库\p{BC=NSM},因为现在只有ICU和Perl才能访问所有 Unicode属性.普通的Java正则表达式库仅支持几个标准的Unicode属性.在JDK7中,虽然支持Unicode Script propery,这对Block属性来说几乎是无限的.因此,你可以在JDK7中编写\p{Script=Latin}或者 \p{SC=Latin},或者简写\p{Latin},从拉丁文脚本中获取任何字符.这导致了非常普遍的需要[\p{Latin}\p{Common}\p{Inherited}].

请注意,这不会删除您可能认为的所有角色的"重音"标记!有很多人不会这样做.例如,你不能转换ĐdØØ的方式.为此,您需要将代码点减少到与Unicode归类表中相同的主要归类强度匹配的代码点.

\p{Mn}事情失败的另一个地方当然是封闭标记\p{Me},显然,还有\p{Diacritic}一些不是标记的字符.遗憾的是,你需要完全的财产支持,这意味着JNI要么是ICU,要么是Perl.我担心Java支持很多问题.

哦等等,我看到你是葡萄牙人.如果您只处理葡萄牙语文本,那么您应该没有任何问题.

但是,我不打算删除重音,我打赌,而是你希望能够匹配"不区分重音"的东西,对吧?如果是这样,那么您可以使用ICU4J(ICU for Java)collat​​or类来完成.如果您比较主要强度,重音符号将不计算在内.我一直这样做,因为我经常处理西班牙文本.我有一个例子说明如何在西班牙人坐在这里,如果你需要的话.

  • yeah, I totally understood all of this (5认同)

Mat*_*ius 6

我花了一段时间,但我把它们都捞出来了:

\n\n

这是正则表达式应该包含所有 zalgo 字符,包括在“正常”范围内绕过的字符。

\n\n
([\\u0300\xe2\x80\x93\\u036F\\u1AB0\xe2\x80\x93\\u1AFF\\u1DC0\xe2\x80\x93\\u1DFF\\u20D0\xe2\x80\x93\\u20FF\\uFE20\xe2\x80\x93\\uFE2F\\u0483-\\u0486\\u05C7\\u0610-\\u061A\\u0656-\\u065F\\u0670\\u06D6-\\u06ED\\u0711\\u0730-\\u073F\\u0743-\\u074A\\u0F18-\\u0F19\\u0F35\\u0F37\\u0F72-\\u0F73\\u0F7A-\\u0F81\\u0F84\\u0e00-\\u0eff\\uFC5E-\\uFC62])\n
Run Code Online (Sandbox Code Playgroud)\n\n

希望这可以为您节省一些时间。

\n