C# Quitar acentuación de String (Nueva duda)

Iniciado por n-utz, 13 Julio 2017, 00:19 AM

0 Miembros y 1 Visitante están viendo este tema.

n-utz

Buenas gente, les vengo con unas dudas.

Tengo que desarrollar un algoritmo que cambie las letras puntuadas o simbolos "no comunes" como ' ñ ', ' á ', etc, de un String.

Estuve leyendo que tengo que usar una función llamada Normalize, y que hay 4 formas de normalizar.

Lo que no entiendo de qué forma "normaliza" dicha función, y qué variantes tiene cada una de sus formas "C, D, .. ".

Ya busqué en el BIG BROWSER pero no encontré ninguna explicación clara o con ejemplos entendibles.



Me puse a hacer ejemplos manuales y por lo menos entendí la diferencia entre FormD y FormC, pero ahora tengo otra duda.

Si tengo una Lista de Strings

List<String> lista;

Y tengo un metodo llamemoslo reverse(), que da vuelta los Strings.

Ahora si yo quiero dar vuelta con dicho metodo cada String de la Lista, como podria hacerlo? Con un select? Como sería la sintaxis??

Sin tener la necesidad de hacerlo con un for o foreach obviamente.

79137913

HOLA!!!

El metodo correcto a mi parecer seria un ForEach normal o un For con index.

Para hacerlo todo de una podrias utilizar LinQ:
Código (vbnet) [Seleccionar]
Lista.ForEach(itm => itm.value= strreverse(value));

GRACIAS POR LEER!!!
"Como no se puede igualar a Dios, ya he decidido que hacer, ¡SUPERARLO!"
"La peor de las ignorancias es no saber corregirlas"

79137913                          *Shadow Scouts Team*

Eleкtro

#2
A la pregunta nº1, aquí lo tienes todo bien explicado y con ejemplos de las secuencias/composiciones Unicode resultantes en cada tipo de normalización:


Para lo que tú quieres hacer en concreto, en mi opinión te convendría hacerlo de la siguiente manera, lo que basicamente consistiría en descomponer las secuencias/composiciones Unicode de cada caracter, y simplemente ignorar los caracteres de puntuación en cada secuencia, por ejemplo si "á" = "a" + "´", entonces nos quedamos solamente con "a".

C#
Código (csharp) [Seleccionar]
// ***********************************************************************
// Author   : Elektro
// Modified : 09-February-2016
// ***********************************************************************

#region " Usings "

using System.ComponentModel;
using System.Diagnostics;
using System.Globalization;
using System.Text;

#endregion

#region " String Extensions "

// namespace StringExtensions {

/// ----------------------------------------------------------------------------------------------------
/// <summary>
/// Contains custom extension methods to use with the <see cref="System.String"/> type.
/// </summary>
/// ----------------------------------------------------------------------------------------------------
[ImmutableObject(true)]
public static class Normalization {

   #region " Public Extension Methods "

   /// ----------------------------------------------------------------------------------------------------
   /// <summary>
   /// Transforms the diacritic characters in a Unicode string, into standard decomposited characters.
   /// </summary>
   /// ----------------------------------------------------------------------------------------------------
   /// <example> This is a code example.
   /// <code>
   /// string str = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics();
   /// Console.WriteLine(str); // Result: "aeiou aeiou aeiou nN cC"
   /// </code>
   /// </example>
   /// ----------------------------------------------------------------------------------------------------
   /// <param name="sender">
   /// The source string.
   /// </param>
   /// ----------------------------------------------------------------------------------------------------
   /// <returns>
   /// The resulting normalized string.
   /// </returns>
   /// ----------------------------------------------------------------------------------------------------
   [DebuggerStepThrough()]
   [EditorBrowsable(EditorBrowsableState.Advanced)]
   public static string NormalizeDiacritics(this string sender) {

       StringBuilder sb = new StringBuilder();

       foreach (char c in sender.Normalize(NormalizationForm.FormKD)) {
           switch (CharUnicodeInfo.GetUnicodeCategory(c)) {
               case UnicodeCategory.NonSpacingMark:
                   break; // Do nothing.
               case UnicodeCategory.SpacingCombiningMark:
                   break; // Do nothing.
               case UnicodeCategory.EnclosingMark:
                   break; // Do nothing.

               default:
                   sb.Append(c);
                   break;
           }
       }

       return sb.ToString();

   }

   #endregion

}

// }

#endregion


VB.NET
Código (vbnet) [Seleccionar]
' ***********************************************************************
' Author   : Elektro
' Modified : 09-February-2016
' ***********************************************************************

#Region " Option Statements "

Option Strict On
Option Explicit On
Option Infer Off

#End Region

#Region " Imports "

Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Globalization
Imports System.Text

#End Region

#Region " String Extensions "

' Namespace Text.Extensions.[String]

''' ----------------------------------------------------------------------------------------------------
''' <summary>
''' Contains custom extension methods to use with the <see cref="System.String"/> type.
''' </summary>
''' ----------------------------------------------------------------------------------------------------
<ImmutableObject(True)>
<HideModuleName>
Public Module Normalization

#Region " Public Extension Methods "

   ''' ----------------------------------------------------------------------------------------------------
   ''' <summary>
   ''' Transforms the diacritic characters in a Unicode string, into standard decomposited characters.
   ''' </summary>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <example> This is a code example.
   ''' <code>
   ''' Dim str As String = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics()
   ''' Console.WriteLine(str) ' Result: "aeiou aeiou aeiou nN cC"
   ''' </code>
   ''' </example>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <param name="sender">
   ''' The source string.
   ''' </param>
   ''' ----------------------------------------------------------------------------------------------------
   ''' <returns>
   ''' The resulting normalized string.
   ''' </returns>
   ''' ----------------------------------------------------------------------------------------------------
   <DebuggerStepThrough>
   <Extension>
   <EditorBrowsable(EditorBrowsableState.Advanced)>
   Public Function NormalizeDiacritics(ByVal sender As String As String)

       Dim sb As New StringBuilder

       For Each c As Char In sender.Normalize(NormalizationForm.FormKD)

           Select Case CharUnicodeInfo.GetUnicodeCategory(c)

               Case UnicodeCategory.NonSpacingMark, UnicodeCategory.SpacingCombiningMark, UnicodeCategory.EnclosingMark
                   ' Do nothing.
                   Exit Select

               Case Else
                   sb.Append(c)

           End Select

       Next c

       Return sb.ToString()

   End Function

#End Region

End Module

' End Namespace

#End Region


Ejemplo de uso:

C#
Código (csharp) [Seleccionar]
string str = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics();
Debug.WriteLine(str); // Result: "aeiou aeiou aeiou nN cC"


VB.NET
Código (vbnet) [Seleccionar]
Dim str As String = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics()
Debug.WriteLine(str) ' Result: "aeiou aeiou aeiou nN cC"


PD: El código que he compartido es tan solo un diminuto extracto de mi framework comercial llamado ElektroKit, un kit de desarrollo con controles de usuario enfocados a la tecnología Windows Forms y también con una muy extensa variedad de funcionalidades para cubrir un abanico de campos relacionados con la programación en general. Este framework, si a alguien le interesa, lo pueden encontrar a la venta en mi frma de usuario aquí abajo.

Espero haber sido de ayuda.

Saludos








n-utz

Buenisimo, si hoy a la mañana llegué a una solución muy parecida, desglosando el string con FormD, pero solo purgandolo con NonSpacingMark, me quedan dudas de que purga el SpacingCombiningMark y el EnclosingMark, pero supongo que en el link que me pasaste me sacaré las dudas.

Muchas gracias Elektro, y resulta interesante ver el framework que creaste.

Les paso la solución que terminé usando:


main
{
List<string> textoOriginal;
textoOriginal.Select(linea => ModifyText(linea) )
}

public string ModifyText (string texoOriginal)
{
   string textoNormalizado = textoOriginal.Normalize(NormalizationForm.FormD);
   var textoResultado = new StringBuilder();

   for(int i = 0; i < textoNormalizado.Length; i++)
   {
    var char = 
    System.Globalization.CharUnicodeInfo.GetUnicodeCategory(textoNormalizado[i]);

    if (char != System.Globalization.UnicodeCategory.NonSpacingMark)
         textoResultado.Append(textoNormalizao[i]);
   }
}


Eleкtro

Cita de: n-utz en 14 Julio 2017, 00:22 AM
Buenisimo, si hoy a la mañana llegué a una solución muy parecida, desglosando el string con FormD, pero solo purgandolo con NonSpacingMark, me quedan dudas de que purga el SpacingCombiningMark y el EnclosingMark, pero supongo que en el link que me pasaste me sacaré las dudas.

Yo tampoco soy aquí ningún gurü en el conocimiento de sets de caracteres Unicode y su implementación ni la desglosación, pero en teoría SpacingCombiningMark se refiere a un signo de puntuación que modifica la longitud del glifo del caracter/vocal base, por ejemplo:

U+093E - DEVANAGARI VOWEL SIGN AA


Y EnclosingMark, según lo que yo entendí en su día, sería un signo de puntuación que rodea a los demás caracteres en la composición del caracter.

Saludos