问题是,如你所知,Unicode图表中有数千个字符,我想将所有相似的字符转换为英文字母中的字母.
例如,这里有一些转换:
?->H ?->V ?->Y ?->O ?->C t?? ?????y --> the Family ...
我看到有超过20个版本的字母A/a.而且我不知道如何对它们进行分类.它们看起来像大海捞针.
完整的unicode字符列表位于http://www.ssec.wisc.edu/~tomw/java/unicode.html 或http://unicode.org/charts/charindex.html.只需向下滚动即可看到字母的变化.
如何用Java转换所有这些?请帮我 :(
重新发布我的帖子如何从.NET中的字符串中删除变音符号(重音符号)?
这种方法在java中工作正常(纯粹是为了删除变音符号也称为重音).
它基本上将所有重音字符转换为deAccented对应字符,然后将它们组合成变音符号.现在你可以使用正则表达式去除变音符号.
import java.text.Normalizer; import java.util.regex.Pattern; public String deAccent(String str) { String nfdNormalizedString = Normalizer.normalize(str, Normalizer.Form.NFD); Pattern pattern = Pattern.compile("\\p{InCombiningDiacriticalMarks}+"); return pattern.matcher(nfdNormalizedString).replaceAll(""); }
它是Apache Commons Lang的一部分.3.0.
org.apache.commons.lang3.StringUtils.stripAccents("Añ");
回报 An
另请参阅http://www.drillio.com/en/software-development/java/removing-accents-diacritics-in-any-language/
试图"全部转换"是解决问题的错误方法.
首先,您需要了解您尝试做的事情的局限性.正如其他人所指出的,变音符号的存在是有原因的:它们本质上是该语言字母表中的独特字母,具有自己的意义/声音等.删除这些标记与替换英语单词中的随机字母相同.这是在您考虑使用西里尔语和其他基于脚本的文本(例如阿拉伯语)之前,这些文本根本无法"转换"为英语.
如果你因为某种原因必须转换字符,那么唯一合理的方法就是首先减少手头任务的范围.考虑输入的来源 - 如果您正在为"西方世界"编写应用程序(使用与任何语言一样好的短语),那么您将不太可能需要解析阿拉伯字符.类似地,Unicode字符集包含数百个数学和图形符号:用户没有(简单)方式直接输入这些符号,因此您可以假设它们可以被忽略.
通过采用这些逻辑步骤,您可以减少要解析的可能字符数,使基于字典的查找/替换操作成为可能.然后它变成了一些创建字典的轻微无聊的工作,以及执行替换的一项微不足道的任务.如果您的语言支持原生Unicode字符(如Java所做)并正确优化静态结构,则此类查找和替换往往会非常快速.
这来自于曾经允许最终用户搜索包含变音字符的书目数据所需的应用程序的经验.查询数组(就像我们的情况一样)花了大约一个人的时间来制作,以涵盖所有西欧语言的所有变音符号.
由于将"家庭"变成"tђєŦค3เℓy"的编码实际上是随机的,并且不遵循任何可以通过所涉及的Unicode码点的信息解释的算法,因此没有通用的方法来解决这种算法.
您需要将Unicode字符的映射构建为类似的拉丁字符.您可以通过一些智能机器学习表示Unicode代码点的实际字形来完成此操作.但我认为这方面的努力将大于手动构建映射.特别是如果你有大量的例子可以用来构建你的映射.
澄清一下:一些替换实际上可以通过Unicode数据解决(正如其他答案所示),但有些字母与它们类似的拉丁字符没有任何合理的关联.
例子:
"ђ"(U + 0452 CYRILLIC SMALL LETTER DJE)与"d"比"h"更相关,但用于表示"h".
"Ŧ"(U + 0166 LATIN CAPITAL LETTER T WITH STROKE)与"T"(顾名思义)有些相关,但用于表示"F".
"ค"(U + 0E04 THAI CHARACTER KHO KHWAI)完全与任何拉丁字符无关,在您的示例中用于表示"a"
原始请求已经回答了.
但是,我正在为那些可能正在寻找通用音译代码的人发布以下答案,以便将任何字符集音译为Java中的拉丁语/英语.
音译的天真含义:它的最终形式/目标字符集中的翻译字符串听起来像是原始形式的字符串.如果我们想将任何字符集音译为拉丁语(英文字母),那么ICU4(java中的ICU4J库)就可以完成这项工作.
这是java中的代码片段:
import com.ibm.icu.text.Transliterator; //ICU4J library import public static String TRANSLITERATE_ID = "NFD; Any-Latin; NFC"; public static String NORMALIZE_ID = "NFD; [:Nonspacing Mark:] Remove; NFC"; /** * Returns the transliterated string to convert any charset to latin. */ public static String transliterate(String input) { Transliterator transliterator = Transliterator.getInstance(TRANSLITERATE_ID + "; " + NORMALIZE_ID); String result = transliterator.transliterate(input); return result; }
经过测试的字符串:ÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝß
经过测试:
Apache Commons Lang3的输出:AAAAAÆCEEEEIIIIÐNOOOOOØUUUUYß
ICU4j的输出:AAAAAÆCEEEEIIIIÐNOOOOOØUUUUYß
JUnidecode的输出:AAAAAAECEEEEIIIIDNOOOOOOUUUUUss(问题与Ý和另一个问题)
Unidecode的输出:AAAAAAECEEEEIIIIDNOOOOOOUUUUYss
最后的选择是最好的.
如果需要转换"òéışöç-> oeisoc",您可以使用此作为起点:
public class AsciiUtils { private static final String PLAIN_ASCII = "AaEeIiOoUu" // grave + "AaEeIiOoUuYy" // acute + "AaEeIiOoUuYy" // circumflex + "AaOoNn" // tilde + "AaEeIiOoUuYy" // umlaut + "Aa" // ring + "Cc" // cedilla + "OoUu" // double acute ; private static final String UNICODE = "\u00C0\u00E0\u00C8\u00E8\u00CC\u00EC\u00D2\u00F2\u00D9\u00F9" + "\u00C1\u00E1\u00C9\u00E9\u00CD\u00ED\u00D3\u00F3\u00DA\u00FA\u00DD\u00FD" + "\u00C2\u00E2\u00CA\u00EA\u00CE\u00EE\u00D4\u00F4\u00DB\u00FB\u0176\u0177" + "\u00C3\u00E3\u00D5\u00F5\u00D1\u00F1" + "\u00C4\u00E4\u00CB\u00EB\u00CF\u00EF\u00D6\u00F6\u00DC\u00FC\u0178\u00FF" + "\u00C5\u00E5" + "\u00C7\u00E7" + "\u0150\u0151\u0170\u0171" ; // private constructor, can't be instanciated! private AsciiUtils() { } // remove accentued from a string and replace with ascii equivalent public static String convertNonAscii(String s) { if (s == null) return null; StringBuilder sb = new StringBuilder(); int n = s.length(); for (int i = 0; i < n; i++) { char c = s.charAt(i); int pos = UNICODE.indexOf(c); if (pos > -1){ sb.append(PLAIN_ASCII.charAt(pos)); } else { sb.append(c); } } return sb.toString(); } public static void main(String args[]) { String s = "The result : È,É,Ê,Ë,Û,Ù,Ï,Î,À,Â,Ô,è,é,ê,ë,û,ù,ï,î,à,â,ô,ç"; System.out.println(AsciiUtils.convertNonAscii(s)); // output : // The result : E,E,E,E,U,U,I,I,A,A,O,e,e,e,e,u,u,i,i,a,a,o,c } }
JDK 1.6提供了可用于此任务的java.text.Normalizer类.
在这里查看示例