22

文字のUnicodeコードポイントを返すにはどうすればよいですか?たとえば、入力が「A」の場合、出力は「U+0041」になります。理想的には、ソリューションはサロゲートペアを処理する必要があります。

コードポイントとは、コードユニットとは異なるUnicodeによる実際のコードポイント意味ます(UTF8には8ビットのコードユニット、UTF16には16ビットのコードユニット、UTF32には32ビットのコードユニットがあります。後者の場合、値はエンディアンネスを考慮した後、コードポイントに等しくなります)。

4

7 に答える 7

13

次のコードは、string入力のコードポイントをコンソールに書き込みます。

string input = "\uD834\uDD61";

for (var i = 0; i < input.Length; i += char.IsSurrogatePair(input, i) ? 2 : 1)
{
    var codepoint = char.ConvertToUtf32(input, i);

    Console.WriteLine("U+{0:X4}", codepoint);
}

出力:

U + 1D161

.NETの文字列はUTF-16でエンコードされcharているため、文字列を構成する値を最初にUTF-32に変換する必要があります。

于 2012-12-15T16:46:27.530 に答える
11

C#の文字は実際にはUTF16コードポイントであるため、簡単です。

char x = 'A';
Console.WriteLine("U+{0:x4}", (int)x);

コメントに対処するためにchar、C#のAは16ビットの数値であり、UTF16コードポイントを保持します。16を超えるコードポイントでは、ビットスペースをC#文字で表すことはできません。C#の文字は可変幅ではありません。ただし、文字列は2つの文字を続けて持つことができ、それぞれがコードユニットであり、UTF16コードポイントを形成します。文字列入力と16ビットスペースを超える文字がある場合は、別の回答で提案されているように、char.IsSurrogatePairとを使用できます。Char.ConvertToUtf32

string input = ....
for(int i = 0 ; i < input.Length ; i += Char.IsSurrogatePair(input,i) ? 2 : 1)
{
    int x = Char.ConvertToUtf32(input, i);
    Console.WriteLine("U+{0:X4}", x);
}
于 2012-12-15T16:33:33.800 に答える
4

C#はユニコードコードポイントをに格納できません。2バイトしかないため、ユニコードコードポイントは通常その長さを超えますcharchar解決策は、コードポイントを一連のバイト(バイト配列または32ビットプリミティブに「フラット化」)または文字列として表すことです。受け入れられた回答はUTF32に変換されますが、それが常に理想的であるとは限りません。

これは、文字列をUnicodeコードポイントコンポーネントに分割するために使用するコードですが、ネイティブUTF-16エンコーディングは保持されます。結果は、C#/。NETでネイティブに(サブ)文字列を比較するために使用できる列挙型です。

    public class InvalidEncodingException : System.Exception
    { }

    public static IEnumerable<string> UnicodeCodepoints(this string s)
    {
        for (int i = 0; i < s.Length; ++i)
        {
            if (Char.IsSurrogate(s[i]))
            {
                if (s.Length < i + 2)
                {
                    throw new InvalidEncodingException();
                }
                yield return string.Format("{0}{1}", s[i], s[++i]);
            }
            else
            {
                yield return string.Format("{0}", s[i]);
            }
        }
    }
}
于 2017-04-07T14:14:24.187 に答える
3

.NET Core 3.0以降では、RuneStructを使用できます。

// Note that  and  are encoded using surrogate pairs
// but A, B, C and ✋ are not
var runes = "ABC✋&quot;.EnumerateRunes();

foreach (var r in runes)
    Console.Write($"U+{r.Value:X4} ");
        
// Writes: U+0041 U+0042 U+0043 U+270B U+1F609 U+1F44D
于 2021-03-05T18:32:50.470 に答える
2

実際、@ Yogendra Singhの回答にはいくつかのメリットがあり、現在、反対票を投じているのは1つだけです。仕事はこのように行うことができます

    public static IEnumerable<int> Utf8ToCodePoints(this string s)
    {
        var utf32Bytes = Encoding.UTF32.GetBytes(s);
        var bytesPerCharInUtf32 = 4;
        Debug.Assert(utf32bytes.Length % bytesPerCharInUtf32 == 0);
        for (int i = 0; i < utf32bytes.Length; i+= bytesPerCharInUtf32)
        {
            yield return BitConverter.ToInt32(utf32bytes, i);
        }
    }

でテスト済み

    var surrogatePairInput = "abc";
    Debug.Assert(surrogatePairInput.Length == 5);
    var pointsAsString = string.Join(";" , 
        surrogatePairInput
        .Utf8ToCodePoints()
        .Select(p => $"U+{p:X4}"));
    Debug.Assert(pointsAsString == "U+0061;U+0062;U+0063;U+1F4A9");

うんこマークは代理ペアとして表されるため、例は適切です。

于 2017-06-21T15:12:26.630 に答える
-1

私はmsdnフォーラムで小さな方法を見つけました。お役に立てれば。

    public int get_char_code(char character){ 
        UTF32Encoding encoding = new UTF32Encoding(); 
        byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray()); 
        return BitConverter.ToInt32(bytes, 0); 
    } 
于 2012-12-15T16:39:51.797 に答える
-1
public static string ToCodePointNotation(char c)
{

    return "U+" + ((int)c).ToString("X4");
}

Console.WriteLine(ToCodePointNotation('a')); //U+0061
于 2012-12-15T16:46:13.080 に答える