【问题标题】:Convert International String to \u Codes in java在java中将国际字符串转换为\u代码
【发布时间】:2011-09-07 23:32:57
【问题描述】:

如何将国际(例如俄语)字符串转换为 \u 数字(unicode 数字)
例如\u041e\u041aOK

【问题讨论】:

    标签: java unicode escaping unicode-escapes


    【解决方案1】:

    有一个JDK tools通过命令行执行如下:

    native2ascii -encoding utf8 src.txt output.txt
    

    例子:

    src.txt

    بسم الله الرحمن الرحيم
    

    output.txt

    \u0628\u0633\u0645 \u0627\u0644\u0644\u0647 \u0627\u0644\u0631\u062d\u0645\u0646 \u0627\u0644\u0631\u062d\u064a\u0645
    

    如果你想在你的 Java 应用程序中使用它,你可以把这个命令行包装成这样:

    String pathSrc = "./tmp/src.txt";
    String pathOut = "./tmp/output.txt";
    String cmdLine = "native2ascii -encoding utf8 " + new File(pathSrc).getAbsolutePath() + " " + new File(pathOut).getAbsolutePath();
    Runtime.getRuntime().exec(cmdLine);
    System.out.println("THE END");
    

    然后读取新文件的内容。

    【讨论】:

    【解决方案2】:

    您可以使用org.apache.commons.lang.StringEscapeUtils 中的escapeJavaStyleString

    【讨论】:

    • 在 3.x 版本中,此方法似乎已重命名为 escapeJava
    • 并且不会转义到 \uXXXX
    • 你最好不要使用它;)查看答案:stackoverflow.com/a/4298836/115493
    • 此方法还可以转义其他特殊符号,例如。引号 (")。这可能是不受欢迎的行为。
    【解决方案3】:

    我也有这个问题。我有一些带有特殊字符的葡萄牙语文本,但这些字符已经是 unicode 格式(例如:\u00e3)。

    所以我想将S\u00e3o 转换为São

    我是使用 apache commons StringEscapeUtils 完成的。正如@sorin-sbarnea 所说。可以下载here

    使用方法unescapeJava,像这样:

    String text = "S\u00e3o"
    text = StringEscapeUtils.unescapeJava(text);
    System.out.println("text " + text);
    

    (也有escapeJava的方法,不过这个是把unicode字符放在字符串里的。)

    如果有人知道纯 Java 的解决方案,请告诉我们。

    【讨论】:

    • 你反其道而行之,这不是 OP 所要求的。
    【解决方案4】:

    这是ArtB's answer的改进版:

        StringBuilder b = new StringBuilder();
    
        for (char c : input.toCharArray()) {
            if (c >= 128)
                b.append("\\u").append(String.format("%04X", (int) c));
            else
                b.append(c);
        }
    
        return b.toString();
    

    此版本会转义所有非 ASCII 字符,并且可以正确处理低 Unicode 代码点,例如 Ä

    【讨论】:

    • 它是否适用于多字节字符,例如当一行中的 4-6-8 个字节(2、3、4 个 java char 值)只代表一个符号?
    • 它没有,因为它使用单个 char 进行迭代。
    【解决方案5】:

    答案分三部分

    1. 获取每个字符的 Unicode
    2. 确定它是否在西里尔文页面中
    3. 转换为十六进制。

    要获取每个字符,您可以使用 charAt()toCharArray() 方法遍历字符串。

    for( char c : s.toCharArray() )
    

    char 的值是 Unicode 值。

    Cyrillic Unicode 字符是以下范围内的任何字符:

    Cyrillic:            U+0400–U+04FF ( 1024 -  1279)
    Cyrillic Supplement: U+0500–U+052F ( 1280 -  1327)
    Cyrillic Extended-A: U+2DE0–U+2DFF (11744 - 11775)
    Cyrillic Extended-B: U+A640–U+A69F (42560 - 42655)
    

    如果在此范围内,则为西里尔文。只需执行 if 检查。如果它在范围内,请使用Integer.toHexString() 并在前面加上"\\u"。放在一起应该是这样的:

    final int[][] ranges = new int[][]{ 
            {  1024,  1279 }, 
            {  1280,  1327 }, 
            { 11744, 11775 }, 
            { 42560, 42655 },
        };
    StringBuilder b = new StringBuilder();
    
    for( char c : s.toCharArray() ){
        int[] insideRange = null;
        for( int[] range : ranges ){
            if( range[0] <= c && c <= range[1] ){
                insideRange = range;
                break;
            }
        }
    
        if( insideRange != null ){
            b.append( "\\u" ).append( Integer.toHexString(c) );
        }else{
            b.append( c );
        }
    }
    
    return b.toString();
    

    编辑: 可能应该检查c &lt; 128 并反转ifelse 主体;你可能应该转义所有不是 ASCII 的东西。我在阅读您的问题时可能过于直白了。

    【讨论】:

    • 这是我上下文中的正确答案。但是,我认为“getCharArray()”应该是“toCharArray”。
    • @JenS。谢谢,确实,方法其实是toCharArray()
    • 这对所有 Unicode 字符都不正确!例如对于德语Ä,它返回\uC4,而不是\u00c4
    • @m01 我相信问题的原始形式是专门针对俄语字符的。
    • 俄语仅作为示例。不过,您的示例还可以;范围检查 if 防范这种情况。另请参阅我对通用方法的回答。
    【解决方案6】:

    Java 附带一个名为native2ascii 的命令行工具。这会将 unicode 文件转换为 ASCII 转义文件。我发现这是为本地化生成 .properties 文件的必要步骤。

    【讨论】:

      【解决方案7】:

      如果您需要它来编写.properties 文件,您只需将字符串添加到属性对象中,然后将其保存到文件中。它将负责转换。

      【讨论】:

      • 那么您需要确保将文件保存为 UTF-8 格式(也许 UTF-16 或 UCS-2/4 可以),否则您会遇到问题。
      • @ArtB:不,Properties 始终将输入文件解释为ISO-8859-1(第一个 unicode 页),并保存为该编码。这就是为什么它需要\uXXXX 转义并在保存时创建它们。尽管从 Java 1.6 版开始,Properties 允许从 Reader 对象读取输入,以便您能够制作自己的专有 UTF-8 属性文件格式。
      • 哦...这不会导致非首页语言出现问题吗?
      • 是的,因为\uXXXX 编码的空间效率低于 UTF-8 或 UTF-16,因此对于主要使用 8859-1 之外的字符的语言,它会产生相对较大的文件。这也使得在任何不知道这种特殊编码的编辑器中都无法编辑这些文件。但至少它允许将所有 unicode 文本保存和加载到 Java VM 通常支持的扩展范围内。
      • 这就是为什么我写Java VM 普遍支持的扩展。实际上它支持 BMP 之外的字符,因为 Java 将这些字符视为代理对,因此它们也可以编码为 \u 对。但是 Java 中对代理项的支持程度差异很大,从几乎不存在到在 XML-Parsers 或某些 Swing 组件中有所支持。此外,java.lang 中的许多基本字符串操作例程现在似乎都是代理项(据我所知,regexp 除外),但如果您愿意,您仍然可以在它们中间剪切一个字符串。
      【解决方案8】:

      Apache commons StringEscapeUtils.escapeEcmaScript(String) 返回一个使用 \u 表示法转义的 unicode 字符的字符串。

      "Art of Beer ? ?" -> "Art of Beer \u1F3A8 \u1F37A"
      

      【讨论】:

        【解决方案9】:

        有一个开源 java 库 MgntUtils 有一个实用程序,可以将字符串转换为 unicode 序列,反之亦然:

        result = "Hello World";
        result = StringUnicodeEncoderDecoder.encodeStringToUnicodeSequence(result);
        System.out.println(result);
        result = StringUnicodeEncoderDecoder.decodeUnicodeSequenceToString(result);
        System.out.println(result);
        

        这段代码的输出是:

        \u0048\u0065\u006c\u006c\u006f\u0020\u0057\u006f\u0072\u006c\u0064
        Hello World
        

        该库可以在Maven CentralGithub 找到它作为 maven 工件并带有源代码和 javadoc

        这是StringUnicodeEncoderDecoder类的javadoc

        【讨论】:

        【解决方案10】:

        只是一些基本的方法(灵感来自 native2ascii 工具):

        /**
         * Encode a String like äöü to \u00e4\u00f6\u00fc
         * 
         * @param text
         * @return
         */
        public String native2ascii(String text) {
            if (text == null)
                return text;
            StringBuilder sb = new StringBuilder();
            for (char ch : text.toCharArray()) {
                sb.append(native2ascii(ch));
            }
            return sb.toString();
        }
        
        /**
         * Encode a Character like ä to \u00e4
         * 
         * @param ch
         * @return
         */
        public String native2ascii(char ch) {
            if (ch > '\u007f') {
                StringBuilder sb = new StringBuilder();
                // write \udddd
                sb.append("\\u");
                StringBuffer hex = new StringBuffer(Integer.toHexString(ch));
                hex.reverse();
                int length = 4 - hex.length();
                for (int j = 0; j < length; j++) {
                    hex.append('0');
                }
                for (int j = 0; j < 4; j++) {
                    sb.append(hex.charAt(3 - j));
                }
                return sb.toString();
            } else {
                return Character.toString(ch);
            }
        }
        

        【讨论】:

          【解决方案11】:

          如果使用此 JavaScript 代码,您可能会破解:

          /* convert ? to \uD83D\uDE4C */
          function text_to_unicode(string) {
            'use strict';
          
            function is_whitespace(c) { return 9 === c || 10 === c || 13 === c || 32 === c;  }
            function left_pad(string) { return Array(4).concat(string).join('0').slice(-1 * Math.max(4, string.length)); }
          
            string = string.split('').map(function(c){ return "\\u" + left_pad(c.charCodeAt(0).toString(16).toUpperCase()); }).join('');
          
            return string;
          }
          
          
          /* convert \uD83D\uDE4C to ? */
          function unicode_to_text(string) {
            var  prefix = "\\\\u"
               , regex  = new RegExp(prefix + "([\da-f]{4})","ig")
               ; 
          
            string = string.replace(regex, function(match, backtrace1){
              return String.fromCharCode( parseInt(backtrace1, 16) )
            });
          
            return string;
          }
          

          来源:iCompile - Yet Another JavaScript Unicode Encode/Decode

          【讨论】:

            【解决方案12】:

            此类型名称为解码/非转义 Unicode。 这个site link在线转换器。

            【讨论】:

              猜你喜欢
              • 2016-11-04
              • 2017-02-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-12-10
              • 2018-11-13
              • 1970-01-01
              相关资源
              最近更新 更多