我面临的情况是我在文本中获取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();
}
答案 0 :(得分: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();
}
if
声明你问过这句话:
if (!(Character.isHighSurrogate(c) || Character.isLowSurrogate(c))) {
sb.append(firstChar);
}
理解它的一种方法是将每个操作分解为自己的功能,这样你就可以看到组合符合你的期望:
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);
}
答案 1 :(得分:8)
Java字符串存储为16位字符序列,但它们代表的是unicode字符序列。在unicode术语中,它们存储为代码单元,但是模型代码点。因此,谈论删除代理人有点毫无意义,代理人在字符/代码点表示中不存在(除非你有流氓单一代理人,在这种情况下你还有其他问题)。
相反,您要做的是删除任何在编码时需要代理的字符。这意味着任何超出基本多语言平面的角色。你可以用一个简单的正则表达式来做到这一点:
return query.replaceAll("[^\u0000-\uffff]", "");
答案 2 :(得分:2)
为什么不简单
for (int i = 0; i < query.length(); i++)
char c = query.charAt(i);
if(!isHighSurrogate(c) && !isLowSurrogate(c))
sb.append(c);
你可能应该用“?”替换它们,而不是正确地删除它们。
答案 3 :(得分:0)
好奇。如果char是高代理,是否需要检查下一个?它应该是低代理人。修改后的版本将是:
public static String removeSurrogates(String query) {
StringBuilder sb = new StringBuilder();
for (int i = 0; i < query.length(); i++) {
char ch = query.charAt(i);
if (Character.isHighSurrogate(ch))
i++;//skip the next char is it's supposed to be low surrogate
else
sb.append(ch);
}
return sb.toString();
}
答案 4 :(得分:0)
如果删除,所有这些解决方案都很有用 但如果重新开始,下面会更好
StringBuffer sb = new StringBuffer();
for (int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if(Character.isHighSurrogate(c)){
sb.append('*');
}else if(!Character.isLowSurrogate(c)){
sb.append(c);
}
}
return sb.toString();