una ultimos quitar primeros palabras obtener los longitud length extraer contar caracteres calcular cadena c# .net string unicode unicode-string

ultimos - quitar los primeros 3 caracteres de una cadena c#



¿Por qué la longitud de esta cadena es más larga que la cantidad de caracteres? (8)

Como han señalado las otras respuestas, incluso si hay 3 caracteres visibles, están representados con 4 objetos char . Por eso, la Length es 4 y no 3.

MSDN afirma que

La propiedad Length devuelve el número de objetos Char en esta instancia, no el número de caracteres Unicode.

Sin embargo, si lo que realmente desea saber es la cantidad de "elementos de texto" y no la cantidad de objetos Char , puede usar la clase System.Globalization.StringInfo .

var si = new StringInfo("A𠈓C"); Console.WriteLine(si.LengthInTextElements); // 3

También puede enumerar cada elemento de texto como este

var enumerator = StringInfo.GetTextElementEnumerator("A𠈓C"); while(enumerator.MoveNext()){ Console.WriteLine(enumerator.Current); }

Usar foreach en la cadena dividirá la "letra" del medio en dos objetos char y el resultado impreso no se corresponderá con la cadena.

Este código:

string a = "abc"; string b = "A𠈓C"; Console.WriteLine("Length a = {0}", a.Length); Console.WriteLine("Length b = {0}", b.Length);

productos:

Length a = 3 Length b = 4

¿Por qué? Lo único que podría imaginar es que el carácter chino tiene 2 bytes de longitud y que el método .Length devuelve el recuento de bytes.


Como otros dijeron, no es la cantidad de caracteres en la cadena, sino la cantidad de objetos Char. El carácter 𠈓 es el punto de código U + 20213. Dado que el valor está fuera del rango del tipo de caracteres de 16 bits, está codificado en UTF-16 como el par suplente D840 DE13 .

La forma de obtener la longitud en caracteres se mencionó en las otras respuestas. Sin embargo, debe usarse con cuidado, ya que puede haber muchas formas de representar un personaje en Unicode. "à" puede ser 1 carácter compuesto o 2 caracteres (a + signos diacríticos). La normalización puede ser necesaria, como en el caso de twitter .

Deberías leer esto
joelonsoftware.com/articles/Unicode.html


De acuerdo, en .Net y C # todas las cadenas están codificadas como UTF-16LE . Una string se almacena como una secuencia de caracteres. Cada char encapsula el almacenamiento de 2 bytes o 16 bits.

Lo que vemos "en papel o pantalla" como una sola letra, carácter, glifo, símbolo o signo de puntuación se puede considerar como un único elemento de texto. Como se describe en el Anexo de Norma # Unicode # 29 SEGMENTACIÓN DE TEXTO UNICODE , cada Elemento de Texto está representado por uno o más Puntos de Código. Una lista exhaustiva de Códigos se puede encontrar aquí .

Cada punto de código debe codificarse en binario para su representación interna por una computadora. Como se dijo, cada char almacena 2 bytes. Los puntos de código en o debajo de U+FFFF se pueden almacenar en un solo char . Los puntos de código por encima de U+FFFF se almacenan como un par suplente, utilizando dos caracteres para representar un único punto de código.

Dado lo que ahora sabemos, podemos deducir que un elemento de texto se puede almacenar como un char , como un par sustituto de dos caracteres o, si el elemento de texto está representado por varios puntos de código, una combinación de caracteres individuales y pares sustituidos. Como si eso no fuera lo suficientemente complicado, algunos Elementos de Texto pueden ser representados por diferentes combinaciones de Puntos de Código como se describe en el Anexo # 15 del Estándar Unicode, FORMULARIOS DE NORMALIZACIÓN UNICODE .

Interludio

Por lo tanto, las cadenas que se ven iguales cuando se representan pueden estar compuestas de una combinación diferente de caracteres. Una comparación ordinal (byte por byte) de dos de tales cadenas detectaría una diferencia, esto puede ser inesperado o indeseable.

Puede volver a codificar cadenas .Net. para que usen el mismo Formulario de normalización. Una vez normalizado, dos cadenas con los mismos elementos de texto se codificarán de la misma manera. Para hacer esto, use la función string.Normalize . Sin embargo, recuerde, algunos elementos de texto diferentes se parecen entre sí. : -s

Entonces, ¿qué significa todo esto en relación con la pregunta? El elemento de texto ''𠈓'' está representado por el único punto de código U + 20213 cjk ideografías unificadas extensión b . Esto significa que no se puede codificar como un único char y se debe codificar como un par suplente, utilizando dos caracteres. Esta es la razón por la cual la string b es un char más larga que la string a .

Si necesita contar de manera confiable (ver advertencia) el número de elementos de texto en una string , debe usar la clase System.Globalization.StringInfo como esta.

using System.Globalization; string a = "abc"; string b = "A𠈓C"; Console.WriteLine("Length a = {0}", new StringInfo(a).LengthInTextElements); Console.WriteLine("Length b = {0}", new StringInfo(b).LengthInTextElements);

dando la salida,

"Length a = 3" "Length b = 3"

como se esperaba.

Advertencia

La implementación .Net de la segmentación de texto Unicode en las clases StringInfo y TextElementEnumerator debe ser generalmente útil y, en la mayoría de los casos, generará una respuesta que la persona que llama espera. Sin embargo, como se indica en el Anexo # 29 de la Norma Unicode, "El objetivo de igualar las percepciones de los usuarios no siempre se puede cumplir exactamente porque el texto solo no siempre contiene suficiente información para decidir inequívocamente los límites".


De la documentation de la propiedad String.Length :

La propiedad Length devuelve el número de objetos Char en esta instancia, no el número de caracteres Unicode. La razón es que un carácter Unicode podría estar representado por más de un Char . Utilice la clase System.Globalization.StringInfo para trabajar con cada carácter Unicode en lugar de cada Char .


Esto se debe a que length() solo funciona para puntos de código Unicode que no son mayores que U+FFFF . Este conjunto de puntos de código se conoce como Basic Multilingual Plane (BMP) y usa solo 2 bytes.

Los puntos de código Unicode fuera del BMP se representan en UTF-16 usando pares de sustitución de 4 bytes.

Para contar correctamente el número de caracteres (3), use StringInfo

StringInfo b = new StringInfo("A𠈓C"); Console.WriteLine(string.Format("Length 2 = {0}", b.LengthInTextElements));


Esto se debe a que la propiedad documentation devuelve el número de objetos char , no el número de caracteres Unicode. En su caso, uno de los caracteres Unicode está representado por más de un objeto char (SurrogatePair).

La propiedad Length devuelve el número de objetos Char en esta instancia, no el número de caracteres Unicode. La razón es que un carácter Unicode podría estar representado por más de un Char. Utilice la clase System.Globalization.StringInfo para trabajar con cada carácter Unicode en lugar de cada Char.


Todos los demás le están dando la respuesta superficial, pero también hay una razón más profunda: el número de "caracteres" es una pregunta difícil de definir y puede ser sorprendentemente costoso de calcular, mientras que una propiedad de longitud debe ser rápida.

¿Por qué es difícil de definir? Bueno, hay algunas opciones y ninguna es realmente más válida que otra:

  • El número de unidades de código (bytes u otro fragmento de datos de tamaño fijo; C # y Windows normalmente usan UTF-16 para que devuelva el número de piezas de dos bytes) es ciertamente relevante, ya que la computadora aún necesita tratar los datos en esa forma para muchos propósitos (escribir en un archivo, por ejemplo, se preocupa por los bytes en lugar de los caracteres)

  • El número de puntos de código Unicode es bastante fácil de calcular (aunque O (n) porque debe escanear la cadena para los pares suplentes) y puede importarle a un editor de texto ... pero en realidad no es lo mismo que el número de caracteres impreso en la pantalla (llamado grafemas). Por ejemplo, algunas letras acentuadas se pueden representar de dos formas: un solo punto de código o dos puntos emparejados, uno que representa la letra y el otro que dice "agregar un acento a la letra de mi compañero". ¿Serían el par dos personajes o uno? Puede normalizar cadenas para ayudar con esto, pero no todas las letras válidas tienen una sola representación de punto de código.

  • Incluso el número de grafemas no es igual a la longitud de una cadena impresa, que depende de la fuente, entre otros factores, y dado que algunos caracteres se imprimen con cierta superposición en muchas fuentes (kerning), la longitud de una cadena en la pantalla ¡no es necesariamente igual a la suma de la longitud de los grafenos de todos modos!

  • Algunos puntos Unicode ni siquiera son caracteres en el sentido tradicional, sino más bien algún tipo de marcador de control. Como un marcador de orden de bytes o un indicador de derecha a izquierda. ¿Cuenta esto?

En resumen, la longitud de una cadena es en realidad una pregunta ridículamente compleja y calcularla puede requerir mucho tiempo de CPU y tablas de datos.

Por otra parte, ¿cuál es el punto? ¿Por qué importan estas métricas? Bueno, solo tú puedes responder eso para tu caso, pero personalmente, considero que generalmente son irrelevantes. La limitación de la entrada de datos que encuentro se realiza más lógicamente por los límites de bytes, ya que eso es lo que debe transferirse o almacenarse de todos modos. La limitación del tamaño de visualización se logra mejor con el software del lado de la pantalla: si tiene 100 píxeles para el mensaje, la cantidad de caracteres que ajuste depende de la fuente, etc., que el software de la capa de datos no conoce de todos modos. Finalmente, dada la complejidad del estándar Unicode, es probable que tengas errores en todos los casos si intentas algo más.

Por lo tanto, es una pregunta difícil sin mucho uso de propósito general. El número de unidades de código es trivial de calcular, es solo la longitud de la matriz de datos subyacente, y el más significativo / útil como regla general, con una definición simple.

Es por eso que b tiene una longitud 4 más allá de la explicación superficial de "porque la documentación así lo dice".


Tu personaje en el índice 1 en "A𠈓C" es un SurrogatePair

El punto clave para recordar es que los pares sustituidos representan caracteres individuales de 32 bits .

Puede probar este código y devolverá True

Console.WriteLine(char.IsSurrogatePair("A𠈓C", 1));

Método Char.IsSurrogatePair (String, Int32)

true si el parámetro s incluye caracteres adyacentes en el índice de posiciones e índice + 1 , y el valor numérico del carácter en el índice de posición varía de U + D800 a U + DBFF, y el valor numérico del carácter en el índice de posición + 1 varía desde U + DC00 a U + DFFF; de lo contrario, false .

Esto se explica con más documentation en la propiedad documentation :

La propiedad Length devuelve el número de objetos Char en esta instancia, no el número de caracteres Unicode. La razón es que un carácter Unicode podría estar representado por más de un Char. Utilice la clase System.Globalization.StringInfo para trabajar con cada carácter Unicode en lugar de cada Char.