问题是,如您所知,有数千个字符 在 Unicode 图表中 我想将所有相似的字符转换为英文字母表中的字母。

例如,这里有一些转换:

ҥ->H
Ѷ->V
Ȳ->Y
Ǭ->O
Ƈ->C
tђє Ŧค๓เℓy --> the Family
...

我看到字母A/a有20多个版本。而且我不知道如何对它们进行分类。它们看起来就像大海捞针。

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 /软件开发/ JAVA /删除-口音,变音符号功能于任何语言/

试图“全部转换”是解决这个问题的错误方法。

首先,您需要了解您尝试做的事情的局限性。正如其他人所指出的那样,变音符是有原因的:它们本质上是该语言字母表中的独特字母,具有自己的意义/声音等。删除这些标记与替换英语单词中的随机字母相同。这是在您考虑使用西里尔语和其他基于脚本的文本(例如阿拉伯语)之前,这些文本根本无法“转换”。英语。

如果必须,无论出于何种原因,转换字符,那么唯一合理的方法就是首先减少手头任务的范围。考虑输入的来源 - 如果您正在为“西方世界”编写应用程序。 (使用任何一个好的短语),你不太可能需要解析阿拉伯字符。同样,Unicode字符集包含数百个数学和图形符号:用户没有(简单)方法直接输入这些符号,因此您可以假设它们可以被忽略。

通过采用这些逻辑步骤,您可以减少要解析的可能字符数,以便可以进行基于字典的查找/替换操作。然后它变成了一些创建字典的轻微无聊的工作,以及执行替换的一个微不足道的任务。如果您的语言支持原生Unicode字符(正如Java那样)并正确地优化静态结构,那么查找和替换往往会非常快速。

这来自于为允许最终用户搜索包含变音字符的书目数据所需的应用程序的经验。查询数组(就像我们的情况一样)花了大约一个人的时间来制作,以涵盖所有西欧语言的所有变音符号。

由于将“the Family”转换为“tђє Ŧค๓เℓy”的编码实际上是随机的,并且不遵循任何可以通过所涉及的 Unicode 代码点信息来解释的算法,因此没有通用的方法可以从算法上解决此问题。

您需要将 Unicode 字符映射到与其相似的拉丁字符。您可以通过对代表 Unicode 代码点的实际字形进行一些智能机器学习来做到这一点。但我认为这比手动构建映射要付出更大的努力。特别是如果您有大量可以用来构建映射的示例。

澄清:一些替换实际上可以通过 Unicode 数据来解决(如其他答案所示),但某些字母与它们相似的拉丁字符没有合理的关联。

例子:

  • “ђ”(U+0452 西里尔小写字母 DJE)与“d”的关系比“h”更相关,但用于表示“h”。
  • “Ŧ”(U+0166 带删除线的拉丁文大写字母 T)与“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;
    }

如果需要转换“òéışöç-> 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类。

查看示例此处

字符串测试:ÁÊÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝß

测试:

  • 输出来自 Apache Commons Lang3 :AAAAAÆCEEEEIIIIÐNOOOOOØUUUUYß
  • 输出来自 ICU4j :AAAAAÆCEEEEIIIIÐNOOOOOØUUUUYß
  • 输出来自 JUnidecode :AAAAAAECEEEEIIIIDNOOOOOOUUUUUss(Ý 和另一个问题 问题)
  • 输出来自 统一编码 :AAAAAAECEEEEIIIIDNOOOOOOUUUYSS

最后的选择是最好的。

你可以尝试使用 unidecode, ,它可以作为 红宝石 并作为 cpan 上的 perl 模块. 。本质上,它就像一个巨大的查找表,其中每个 unicode 代码点都与一个 ascii 字符或字符串相关。

没有简单或一般的方法可以做你想要的事情,因为这些字母看起来只是想要转换成拉丁字母,这只是你的主观意见。它们实际上是单独的字母,具有各自独特的名称和声音,恰好看起来像一个拉丁字母。

如果您想进行转换,则必须根据您认为非拉丁字母应转换为的拉丁字母创建自己的翻译表。

(如果您只想删除变音符号,则此主题中有一些答案:如何从.NET中的字符串中删除变音符号(重音符号)?但是,您描述了一个更普遍的问题)

我迟到了,但今天面对这个问题后,我发现这个答案非常好:

String asciiName = Normalizer.normalize(unicodeName, Normalizer.Form.NFD)
    .replaceAll("[^\\p{ASCII}]", "");

参考: https://stackoverflow.com/a/16283863

“转换”的问题任意Unicode到ASCII是一个字符的含义是文化依赖的。例如,德语人士的“ß”应转换为“ss”。而讲英语的人可能会将其转换为“B”。

除此之外,Unicode还有相同字形的多个代码点。

结果是,执行此操作的唯一方法是创建一个包含每个Unicode字符和要将其转换为的ASCII字符的大型表。您可以通过将带有重音的字符标准化为标准化形式KD来获取快捷方式,但并非所有字符标准化为ASCII。另外,Unicode没有定义字形的哪些部分是“重音符号”。

以下是应用程序执行此操作的一小段摘录:

switch (c)
{
    case 'A':
    case '\u00C0':  //  À LATIN CAPITAL LETTER A WITH GRAVE
    case '\u00C1':  //  Á LATIN CAPITAL LETTER A WITH ACUTE
    case '\u00C2':  //  Â LATIN CAPITAL LETTER A WITH CIRCUMFLEX
    // and so on for about 20 lines...
        return "A";
        break;

    case '\u00C6'://  Æ LATIN CAPITAL LIGATURE AE
        return "AE";
        break;

    // And so on for pages...
}

以下课程可以解决问题:

org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top