代码之家  ›  专栏  ›  技术社区  ›  ahmet alp balkan

将符号、重音字母转换为英文字母

  •  123
  • ahmet alp balkan  · 技术社区  · 17 年前

    问题是,正如你所知,有数千个字符 in the Unicode chart 我想把所有相似的字符转换成英语字母表中的字母。

    例如,以下是一些转换:

    Ò¥->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转换所有这些内容?请帮助我:(

    12 回复  |  直到 17 年前
        1
  •  205
  •   Community Mohan Dere    9 年前

    How do I remove diacritics (accents) from a string in .NET?

    此方法在java中运行良好 (纯粹为了去除变音标记或重音) .

    它基本上将所有重音字符转换为非重音字符,然后再转换为组合变音符号。现在您可以使用正则表达式去除变音符号。

    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("");
    }
    
        2
  •  72
  •   Jasper de Vries nndru    11 年前

    这是我们的一部分 Apache Commons Lang

    org.apache.commons.lang3.StringUtils.stripAccents("Añ");
    

    返回 An

    也看到 http://www.drillio.com/en/software-development/java/removing-accents-diacritics-in-any-language/

        3
  •  19
  •   Ian    13 年前

    首先,你需要了解你正在尝试做的事情的局限性。正如其他人所指出的,变音符号的存在是有原因的:它们本质上是该语言字母表中唯一的字母,具有自己的意义/声音等:删除这些标记与替换英语单词中的随机字母一样。这是在你甚至去考虑西里尔语言和其他基于脚本的文本,如阿拉伯语,它不能简单地“转换”为英语。

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

    这来自于开发应用程序的经验,该应用程序需要允许最终用户搜索包含变音字符的书目数据。查找数组(在我们的例子中)大约花了1个人天的时间来制作,以覆盖所有西欧语言的所有发音符号。

        4
  •  16
  •   Joachim Sauer    17 年前

    由于将“家族”转换为“táy”的编码实际上是随机的,并且不遵循任何可以用所涉及的Unicode码点信息解释的算法,因此没有通用的方法从算法上解决这个问题。

    您需要将Unicode字符映射为类似的拉丁字符。您可能可以通过对表示Unicode代码点的实际标志符号进行智能机器学习来实现这一点。但我认为这方面的努力要比手动构建映射更大。特别是如果您有大量的示例可以用来构建映射。

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

    示例:

    • “”(U+0452西里尔小写字母DJE)与“d”的关系大于与“h”的关系,但用于表示“h”。
    • “Åalpha”(U+0166拉丁文大写字母T加上笔划)与“T”(顾名思义)有些关联,但用于表示“F”。
    • “a”(U+0E04泰国字符KHO KHWAI)与任何拉丁字符都没有关系,在您的示例中,它被用来表示“a”
        5
  •  11
  •   cactuschibre mrts    9 年前

    测试的字符串:

    最后一个选择是最好的。

        6
  •  7
  •   Dayanand Gowda    11 年前

    原来的要求已经得到答复。

    然而,我为那些可能正在寻找通用音译代码的人发布以下答案,以便在Java中将任何字符集音译为拉丁语/英语。

    翻译的朴素含义: 如果我们想将任何字符集音译为拉丁语(英语字母),那么ICU4(java中的ICU4J库)将完成这项工作。

        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;
        }
    
        7
  •  6
  •   RealHowTo    17 年前

    如果需要将“Oesoc”转换为“Oesoc”,您可以将其作为起点:

    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
        }
    }
    

    JDK1.6提供了可用于此任务的java.text.Normalizer类。

    here

        8
  •  5
  •   Dour High Arch    8 年前

    将任意Unicode“转换”为ASCII的问题在于字符的含义取决于区域性。例如,一个说德语的人应该转换成“ss”,而一个说英语的人可能会转换成B。

    此外,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...
    }
    
        9
  •  4
  •   Daniel Vandersluis    17 年前

    你可以尝试使用 unidecode ,可作为 ruby gem perl module on cpan . 本质上,它是一个巨大的查找表,其中每个unicode代码点都与ascii字符或字符串相关。

        10
  •  4
  •   Community Mohan Dere    9 年前

    没有简单或通用的方法来做你想做的事情,因为这只是你的主观意见,这些字母看起来像你想转换成的拉丁字母。它们实际上是独立的字母,有自己独特的名称和发音,只是表面上看起来像拉丁字母。

    如果你想要转换,你必须根据你认为非拉丁字母应该转换成的拉丁字母创建你自己的翻译表。

    How do I remove diacritics (accents) from a string in .NET? 但是,您描述了一个更一般的问题)

        11
  •  4
  •   Community Mohan Dere    9 年前

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

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

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

        12
  •  2
  •   TomWolk    9 年前

    org.apache.lucene.analysis.miscellaneous.ASCIIFoldingFilter