簡體   English   中英

在 Java/Android 中找出 UTF-8 字符串中的字符數

[英]Find out number of characters in a UTF-8 string in Java/Android

當字符串以 UTF-8 存儲時,我試圖找出字符串長度。 我嘗試了以下方法:

String str = "मेरा नाम";
Charset UTF8_CHARSET = Charset.forName("UTF-8");
byte[] abc = str.getBytes(UTF8_CHARSET);
int length = abc.length;

這給了我字節數組的長度,但不是字符串中的字符數。

我找到了一個同時顯示 UTF-8 字符串長度和字節長度的網站。 https://mothereff.in/byte-counter假設我的字符串是 मेरा नाम,那么我應該將字符串長度設為 8 個字符而不是 22 個字節。

任何人都可以請指導。

最短的“長度”是在 Unicode代碼點中,作為編號字符的概念,UTF-32。

更正:正如@liudongmiao 提到的,可能應該使用:

int length = string.codePointCount(0, s.length);

在 Java 8 中:

int length = (int) string.codePoints().count();

之前的javas:

int length(String s) {
   int n = 0;
   for (int i = 0; i < s.length(); ++n) {
       int cp = s.codePointAt(i);
       i += Character.charCount(cp);
   }
   return n;
}

Unicode 代碼點可以在 UTF-16 中編碼為一或兩個char

相同的 Unicode 字符可能有變音符號。 它們可以寫成單獨的代碼點:基本字母 + 零個或多個變音符號。 要將字符串規范化為一個 (C=) 壓縮代碼點:

string = java.text.Normalizer.normalize(string, Normalizer.Form.NFC);

順便說一句,出於數據庫目的,UTF-16 長度似乎更有用:

string.length() // Number of UTF-16 chars, every char two bytes.

(在示例中提到的 UTF-32 長度 == UTF-16 長度。)


轉儲功能

一個評論者有一些意想不到的結果:

void dump(String s) {
   int n = 0;
   for (int i = 0; i < s.length(); ++n) {
       int cp = s.codePointAt(i);
       int bytes = Character.charCount(cp);
       i += bytes;
       System.out.printf("[%d] #%dB: U+%X = %s%n",
           n, bytes, cp, Character.getName(cp));
   }
   System.out.printf("Length:%d%n", n);
}

看看http://rosettacode.org/wiki/String_length#Grapheme_Length_4

import java.text.BreakIterator;

public class Grapheme {
  public static void main(String[] args) {
    printLength("møøse");
    printLength("𝔘𝔫𝔦𝔠𝔬𝔡𝔢");
    printLength("J̲o̲s̲é̲");
  }

  public static void printLength(String s) {
    BreakIterator it = BreakIterator.getCharacterInstance();
    it.setText(s);
    int count = 0;
    while (it.next() != BreakIterator.DONE) {
      count++;
    }
    System.out.println("Grapheme length: " + count+ " " + s);
  }
}

輸出:

Grapheme length: 5 møøse
Grapheme length: 7 𝔘𝔫𝔦𝔠𝔬𝔡𝔢
Grapheme length: 4 J̲o̲s̲é̲

您正在尋找的不是字符串長度而是葡萄柚長度。 它為您提供“可見”字符的數量。

String.length()實際上返回以 UTF-16 編碼的字符串中的字符數(其中兩個字節用於編碼一個字符)。 但是,這也適用於大多數 UTF-8 字符,除非您有一個 ASCII 值大於 127 的字符。如果您想手動執行操作而不將其編碼為 UTF-8,您可以執行以下操作

public static int utf8Length(CharSequence sequence) {
        int count = 0;
        for (int i = 0; i < sequence.length(); i++) {
            char ch = sequence.charAt(i);
            if (ch <= 0x7F) {
                count++;
            } else if (ch <= 0x7FF) {
                count += 2;
            } else if (Character.isHighSurrogate(ch)) {
                count += 4;
                ++i;
            } else {
                count += 3;
            }
        }
        return count;
    }

這是UTF-8 規范

在 UTF-8 String.length() 中返回字符數。 如果要獲取字節數,可以使用 String.getBytes().length

例如:

String str = "アンドリューは本當に凄いですだと";

System.out.println(str.length()); // 顯示16對應16個字符 System.out.println(str.getBytes().length); //顯示48對應48個字節

您可以簡單地運行,而不是將password[0]轉換為字節數組

password[0].length();

您還可以將 bytearray 轉換回字符串,然后對其運行 lenght 方法。

    byte[] abc = password[0].getBytes(UTF8_CHARSET);
    String s1 = new String(abc, "UTF-8");
    System.out.println(s1.length());

只需將您的程序保存為utf-8並執行以下操作

        String str= "मेरा नाम";
        System.out.println(str.length());

o/p = 8

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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