如何区分Unicode字符和ASCII字符

时间:2017-08-14 09:49:45

标签: java string unicode char ascii

我想区分下面字符串中的Unicode字符和ASCII字符:

abc\u263A\uD83D\uDE0A\uD83D\uDE22123

我如何辨别角色?任何人都可以帮我解决这个问题吗?我尝试了一些代码,但在某些情况下崩溃了。我的代码出了什么问题?

前三个字符为abc,后三个字符为123。字符串的其余部分是Unicode字符。我想制作一个像这样的字符串数组:

str[0] = 'a';
str[1] = 'b';
str[2] = 'c';
str[3] = '\u263A\uD83D';
str[4] = '\uDE0A\uD83D';
str[5] = '\uDE22';
str[6] = '1';
str[7] = '2';
str[8] = '3';

代码:

private String[] getCharArray(String unicodeStr) {
        ArrayList<String> list = new ArrayList<>();
        for (int i = 0; i < unicodeStr.length(); i++) {
            if (unicodeStr.charAt(i) == '\\') {
                list.add(unicodeStr.substring(i, i + 11));
                i = i + 11;
            } else {
                list.add(String.valueOf(unicodeStr.charAt(i)));
            }
        }
        return list.toArray(new String[list.size()]);
    }

2 个答案:

答案 0 :(得分:0)

您要求的内容并不完全清楚,但如果您想知道某个特定字符是否为ASCII,则可以使用Guava's ChatMatcher.ascii()

if ( CharMatcher.ascii().matches('a') ) {
    System.out.println("'a' is ascii");
}
if ( CharMatcher.ascii().matches('\u263A\uD83D') ) {
    // this shouldn't be printed
    System.out.println("'\u263A\uD83D' is ascii");
}

答案 1 :(得分:0)

Unicode中存在ASCII字符,它们是Unicode代码点U + 0000 - U + 007F,包括在内。

Java字符串以UTF-16表示,它是Unicode的16位字节编码。每个Java char都是UTF-16代码单元。 Unicode代码点U + 0000 - U + FFFF使用1个UTF-16代码单元,因此适合单个char,而Unicode代码点U + 10000和更高代码需要UTF-16 代理对因此需要两个char s。

如果字符串具有表示为实际char值的UTF-16代码单元,那么您可以使用Java string方法来处理代码点,例如:

private String[] getCharArray(String unicodeStr) {
    ArrayList<String> list = new ArrayList<>();
    int i = 0, j;
    while (i < unicodeStr.length()) {
        j = unicodeStr.offsetByCodePoints(i, 1);
        list.add(unicodeStr.substring(i, j));
        i = j;
    }
    return list.toArray(new String[list.size()]);
}

另一方面,如果字符串具有以编码"\uXXXX"格式表示的UTF-16代码单元(即,6个不同的字符 - '\''u',... ),然后事情会变得复杂一些,因为你必须手动解析编码序列。

如果你想保留&#34; \ uXXXX&#34;你的数组中的字符串,你可以做这样的事情:

private boolean isUnicodeEncoded(string s, int index)
{
    return (
        (s.charAt(index) == '\\') &&
        ((index+5) < s.length()) &&
        (s.charAt(index+1) == 'u')
    );
}

private String[] getCharArray(String unicodeStr) {
    ArrayList<String> list = new ArrayList<>();
    int i = 0, j, start;
    char ch;
    while (i < unicodeStr.length()) {
        start = i;
        if (isUnicodeEncoded(unicodeStr, i)) {
            ch = (char) Integer.parseInt(unicodeStr.substring(i+2, i+6), 16);
            j = 6;
        }
        else {
            ch = unicodeStr.charAt(i);
            j = 1;
        }
        i += j;
        if (Character.isHighSurrogate(ch) && (i < unicodeStr.length())) {
            if (isUnicodeEncoded(unicodeStr, i)) {
                ch = (char) Integer.parseInt(unicodeStr.substring(i+2, i+6), 16);
                j = 6;
            }
            else {
                ch = unicodeStr.charAt(i);
                j = 1;
            }
            if (Character.isLowSurrogate(ch)) {
                i += j;
            }
        }
        list.add(unicodeStr.substring(start, i));
    }
    return list.toArray(new String[list.size()]);
}

如果你想解码&#34; \ uXXXX&#34;将数组转换为数组中的实际字符,您可以执行以下操作:

private boolean isUnicodeEncoded(string s, int index)
{
    return (
        (s.charAt(index) == '\\') &&
        ((index+5) < s.length()) &&
        (s.charAt(index+1) == 'u')
    );
}

private String[] getCharArray(String unicodeStr) {
    ArrayList<String> list = new ArrayList<>();
    int i = 0, j;
    char ch1, ch2;
    while (i < unicodeStr.length()) {
        if (isUnicodeEncoded(unicodeStr, i)) {
            ch1 = (char) Integer.parseInt(unicodeStr.substring(i+2, i+6), 16);
            j = 6;
        }
        else {
            ch1 = unicodeStr.charAt(i);
            j = 1;
        }
        i += j;
        if (Character.isHighSurrogate(ch1) && (i < unicodeStr.length())) {
            if (isUnicodeEncoded(unicodeStr, i)) {
                ch2 = (char) Integer.parseInt(unicodeStr.substring(i+2, i+6), 16);
                j = 6;
            }
            else {
                ch2 = unicodeStr.charAt(i);
                j = 1;
            }
            if (Character.isLowSurrogate(ch2)) {
                list.add(String.valueOf(new char[]{ch1, ch2}));
                i += j;
                continue;
            }
        }
        list.add(String.valueOf(ch1));
    }
    return list.toArray(new String[list.size()]);
}

或类似的东西(每https://stackoverflow.com/a/24046962/65863):

private String[] getCharArray(String unicodeStr) {
    Properties p = new Properties();
    p.load(new StringReader("key="+unicodeStr));
    unicodeStr = p.getProperty("key");
    ArrayList<String> list = new ArrayList<>();
    int i = 0;
    while (i < unicodeStr.length()) {
        if (Character.isHighSurrogate(unicodeStr.charAt(i)) &&
            ((i+1) < unicodeStr.length()) &&
            Character.isLowSurrogate(unicodeStr.charAt(i+1)))
        {
            list.add(unicodeStr.substring(i, i+2));
            i += 2;
        }
        else {
            list.add(unicodeStr.substring(i, i+1));
            ++i;
        }
    }
    return list.toArray(new String[list.size()]);
}