如何删除Java中的代理字符?

Slo*_*der 14 java string surrogate-pairs

我面临的情况是我在文本中获取Surrogate字符,我将保存到MySql 5.1.由于此处不支持UTF-16,我想在将其保存到数据库之前通过java方法手动删除这些代理对.

我现在已经编写了以下方法,我很想知道是否有一种直接和最佳的方法来处理这个问题.

在此先感谢您的帮助.

public static String removeSurrogates(String query) {
    StringBuffer sb = new StringBuffer();
    for (int i = 0; i < query.length() - 1; i++) {
        char firstChar = query.charAt(i);
        char nextChar = query.charAt(i+1);
        if (Character.isSurrogatePair(firstChar, nextChar) == false) {
            sb.append(firstChar);
        } else {
            i++;
        }
    }
    if (Character.isHighSurrogate(query.charAt(query.length() - 1)) == false
            && Character.isLowSurrogate(query.charAt(query.length() - 1)) == false) {
        sb.append(query.charAt(query.length() - 1));
    }

    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

Rei*_*ica 8

这里有几件事:

  • Character.isSurrogate(char c):

    char值是代理代码单元,当且仅当它是低代理代码单元或高代理代码单元时.

  • 检查对似乎没有意义,为什么不删除所有代理?

  • x == false 相当于 !x

  • StringBuilder 在不需要同步的情况下(比如永远不会离开本地范围的变量)会更好.

我建议这个:

public static String removeSurrogates(String query) {
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < query.length(); i++) {
        char c = query.charAt(i);
        // !isSurrogate(c) in Java 7
        if (!(Character.isHighSurrogate(c) || Character.isLowSurrogate(c))) {
            sb.append(firstChar);
        }
    }
    return sb.toString();
}
Run Code Online (Sandbox Code Playgroud)

打破if声明

你问过这句话:

if (!(Character.isHighSurrogate(c) || Character.isLowSurrogate(c))) {
    sb.append(firstChar);
}
Run Code Online (Sandbox Code Playgroud)

理解它的一种方法是将每个操作分解为自己的功能,这样你就可以看到组合符合你的期望:

static boolean isSurrogate(char c) {
    return Character.isHighSurrogate(c) || Character.isLowSurrogate(c);
}

static boolean isNotSurrogate(char c) {
    return !isSurrogate(c);
}

...

if (isNotSurrogate(c)) {
    sb.append(firstChar);
}
Run Code Online (Sandbox Code Playgroud)


Tom*_*son 8

Java字符串存储为16位字符序列,但它们代表的是unicode字符序列.在unicode术语中,它们存储为代码单元,但是模型代码点.因此,谈论删除代理人有点毫无意义,代理人在字符/代码点表示中不存在(除非你有流氓单一代理人,在这种情况下你有其他问题).

相反,你想要做的是删除任何在编码时需要代理的字符.这意味着任何超出基本多语言平面的角色.您可以使用简单的正则表达式执行此操作:

return query.replaceAll("[^\u0000-\uffff]", "");
Run Code Online (Sandbox Code Playgroud)