5

Windows Phone では、特定の文字列を 100 ASCII 文字に相当する長さに部分文字列化したいと考えています。

中国語の文字列は 1 文字あたり 3 バイトを使用し、デンマーク語の文字列は 1 文字あたり 2 または 4 バイトを使用し、ロシア語の文字列は 1 文字あたり 4 バイトを使用するため、String.Length は明らかに役に立ちません。

使用可能なエンコードは UTF-8 と UTF-16 のみです。それで、私は何をしますか?

アイデアは次のとおりです。

private static string UnicodeSubstring(string text, int length)
{
    var bytes = Encoding.UTF8.GetBytes(text);

    return Encoding.UTF8.GetString(bytes, 0, Math.Min(bytes.Length, length));
}

ただし、長さは各文字に使用されるバイト数で正しく割り切れる必要があるため、最後の文字は常に正しくレンダリングされます。

4

4 に答える 4

6

1つのオプションは、文字列を調べて、各文字のバイト数を計算することです。

BMPの外部の文字を処理する必要がないことがわかっている場合、これはかなり簡単です。

public string SubstringWithinUtf8Limit(string text, int byteLimit)
{
    int byteCount = 0;
    char[] buffer = new char[1];
    for (int i = 0; i < text.Length; i++)
    {
        buffer[0] = text[i];
        byteCount += Encoding.UTF8.GetByteCount(buffer);
        if (byteCount > byteLimit)
        {
            // Couldn't add this character. Return its index
            return text.Substring(0, i);
        }
    }
    return text;
}

サロゲートペアを処理する必要がある場合は、少し注意が必要です:(

于 2012-09-13T16:59:56.407 に答える
1

1つのオプションは、結果の文字列に「文字」(サポートする必要がある場合はサロゲートペアを含む)を単純に追加し、必要なものの正しい数に変換されるかどうかを確認することです.

于 2012-09-13T17:03:18.563 に答える
0

An idea is also to check if the last character is the Unicode Replace Character , and remove one character until it's rendered correctly.

private static string UnicodeSubstring(string text, int length)
{
    var bytes = Encoding.UTF8.GetBytes(text);
    var result = Encoding.UTF8.GetString(bytes, 0, Math.Min(bytes.Length, length));

    while ('\uFFFD' == result[result.Length - 1])
    {
        result = result.Substring(0, result.Length - 1);
    }

    return result;
}
于 2012-09-13T17:11:19.043 に答える