簡體   English   中英

Java - 從一個混合了UTF-8和非UTF-8字符的字符串中精確計算60個字符

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM