otra - Código de retorno del punto de caracteres en C#
substring c# ejemplos (6)
¿Cómo puedo devolver el Punto de Código Unicode de un personaje? Por ejemplo, si la entrada es "A", entonces la salida debería ser "U + 0041". Idealmente, una solución debería ocuparse de los pares sustitutos .
Con el punto de código me refiero al punto de código real según Unicode , que es diferente de la unidad de código (UTF8 tiene unidades de código de 8 bits, UTF16 tiene unidades de código de 16 bits y UTF32 tiene unidades de código de 32 bits, en este último caso el valor es igual al punto de código, después de tener en cuenta la endianness).
C # no puede almacenar puntos de código Unicode en un char
, ya que char
es de solo 2 bytes y los puntos de código Unicode generalmente superan esa longitud. La solución es representar un punto de código como una secuencia de bytes (como una matriz de bytes o "aplanada" en una primitiva de 32 bits) o como una cadena. La respuesta aceptada se convierte a UTF32, pero eso no siempre es lo ideal.
Este es el código que utilizamos para dividir una cadena en sus componentes de punto de código Unicode, pero conservando la codificación UTF-16 nativa. El resultado es un enumerable que se puede usar para comparar (sub) cadenas de forma nativa en 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]);
}
}
}
}
El siguiente código escribe los puntos de código de una entrada de string
en la consola:
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);
}
Salida:
U+1D161
Como las cadenas en .NET están codificadas en UTF-16, los valores char
que forman la cadena deben convertirse primero a UTF-32.
En realidad, hay algo de mérito en la respuesta de @Yogendra Singh, actualmente el único con voto negativo. El trabajo se puede hacer así.
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);
}
}
Probado con
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");
El ejemplo es relevante porque la pila de poo se representa como un par suplente.
Encontré un pequeño método en el foro msdn . Espero que esto ayude.
public int get_char_code(char character){
UTF32Encoding encoding = new UTF32Encoding();
byte[] bytes = encoding.GetBytes(character.ToString().ToCharArray());
return BitConverter.ToInt32(bytes, 0);
}
Fácil, ya que los caracteres en C # son en realidad puntos de código UTF16:
char x = ''A'';
Console.WriteLine("U+{0:x4}", (int)x);
Para abordar los comentarios, un char
en C # es un número de 16 bits y contiene un punto de código UTF16. Los puntos de código por encima de 16 el espacio de bits no se puede representar en un carácter C #. Los caracteres en C # no son de ancho variable. Sin embargo, una cadena puede tener 2 caracteres seguidos, cada uno de los cuales es una unidad de código, formando un punto de código UTF16. Si tiene una entrada de cadena y caracteres por encima del espacio de 16 bits, puede usar char.IsSurrogatePair
y Char.ConvertToUtf32
, como se sugiere en otra respuesta:
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);
}
public static string ToCodePointNotation(char c)
{
return "U+" + ((int)c).ToString("X4");
}
Console.WriteLine(ToCodePointNotation(''a'')); //U+0061