[英]Java - Count exactly 60 characters from a string with a mixture of UTF-8 and non UTF-8 characters
我有一个字符串,我想保存在只支持UTF8字符的数据库中。 如果字符串大小> 60个字符,我想截断它,只存储前60个字符。 正在使用的Oracle数据库仅支持UTF-8字符。
在Java中使用String.substring(0,59)
返回60个字符,但是当我将其保存在数据库中时,它会被拒绝,因为数据库声称该字符串大于60个字符。
有没有办法找出特定字符串是否包含非UTF8字符。 我发现的一个选择是:
try {
bytes = returnString.getBytes("UTF-8"); } catch (UnsupportedEncodingException e) { // Do something
}
有没有办法可以将其截断为x个字符(数据丢失不是问题),并确保在数据库中保存时只保存x个字符。 例如,如果我有字符串§8§8§8§8§8§8§8
并且我说截断并且只保存5个字符它应该只保存§8§
据我所知,您希望以编码的UTF-8
表示不超过60个字节的方式限制String
长度。 你可以这样做:
String s=…;
CharsetEncoder enc=StandardCharsets.UTF_8.newEncoder();
ByteBuffer bb=ByteBuffer.allocate(60);// note the limit
CharBuffer cb = CharBuffer.wrap(s);
CoderResult r = enc.encode(cb, bb, true);
if(r.isOverflow()) {
System.out.println(s+" is too long for "
+bb.capacity()+" "+enc.charset()+" bytes");
s=cb.flip().toString();
System.out.println("truncated to "+s);
}
这是我的快速黑客:一个函数,用UTF-8编码将字符串截断为给定的字节数:
public static String truncateUtf8(String original, int byteCount) {
if (original.length() * 3 <= byteCount) {
return original;
}
StringBuilder sb = new StringBuilder();
int count = 0;
for (int i = 0; i < original.length(); i++) {
char c = original.charAt(i);
int newCount;
if (c <= 0x7f) newCount = count + 1;
else if (c <= 0x7ff) newCount = count + 2;
else newCount = count + 3;
if (newCount > byteCount) {
break;
}
count = newCount;
sb.append(c);
}
return sb.toString();
}
对于BMP之外的字符,它不能按预期工作 - 将它们计为6个字节而不是4个字节。它也可能会破坏字形集群。 但对于大多数简单的任务,应该没问题。
truncateUtf8("e", 1) => "e"
truncateUtf8("ée", 1) => ""
truncateUtf8("ée", 2) => "é"
truncateUtf8("ée", 3) => "ée"
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.