Foro de elhacker.net

Programación => .NET (C#, VB.NET, ASP) => Mensaje iniciado por: n-utz en 13 Julio 2017, 00:19 am



Título: C# Quitar acentuación de String (Nueva duda)
Publicado por: n-utz en 13 Julio 2017, 00:19 am
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.


Título: Re: C# Quitar acentuación de String (Nueva duda)
Publicado por: 79137913 en 13 Julio 2017, 14:57 pm
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
  1. Lista.ForEach(itm => itm.value= strreverse(value));

GRACIAS POR LEER!!!


Título: Re: C# Quitar acentuación de String (Nueva duda)
Publicado por: Eleкtro en 13 Julio 2017, 16:20 pm
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:

  • http://unicode.org/reports/tr15/ (http://unicode.org/reports/tr15/)

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
  1. // ***********************************************************************
  2. // Author   : Elektro
  3. // Modified : 09-February-2016
  4. // ***********************************************************************
  5.  
  6. #region " Usings "
  7.  
  8. using System.ComponentModel;
  9. using System.Diagnostics;
  10. using System.Globalization;
  11. using System.Text;
  12.  
  13. #endregion
  14.  
  15. #region " String Extensions "
  16.  
  17. // namespace StringExtensions {
  18.  
  19. /// ----------------------------------------------------------------------------------------------------
  20. /// <summary>
  21. /// Contains custom extension methods to use with the <see cref="System.String"/> type.
  22. /// </summary>
  23. /// ----------------------------------------------------------------------------------------------------
  24. [ImmutableObject(true)]
  25. public static class Normalization {
  26.  
  27.    #region " Public Extension Methods "
  28.  
  29.    /// ----------------------------------------------------------------------------------------------------
  30.    /// <summary>
  31.    /// Transforms the diacritic characters in a Unicode string, into standard decomposited characters.
  32.    /// </summary>
  33.    /// ----------------------------------------------------------------------------------------------------
  34.    /// <example> This is a code example.
  35.    /// <code>
  36.    /// string str = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics();
  37.    /// Console.WriteLine(str); // Result: "aeiou aeiou aeiou nN cC"
  38.    /// </code>
  39.    /// </example>
  40.    /// ----------------------------------------------------------------------------------------------------
  41.    /// <param name="sender">
  42.    /// The source string.
  43.    /// </param>
  44.    /// ----------------------------------------------------------------------------------------------------
  45.    /// <returns>
  46.    /// The resulting normalized string.
  47.    /// </returns>
  48.    /// ----------------------------------------------------------------------------------------------------
  49.    [DebuggerStepThrough()]
  50.    [EditorBrowsable(EditorBrowsableState.Advanced)]
  51.    public static string NormalizeDiacritics(this string sender) {
  52.  
  53.        StringBuilder sb = new StringBuilder();
  54.  
  55.        foreach (char c in sender.Normalize(NormalizationForm.FormKD)) {
  56.            switch (CharUnicodeInfo.GetUnicodeCategory(c)) {
  57.                case UnicodeCategory.NonSpacingMark:
  58.                    break; // Do nothing.
  59.                case UnicodeCategory.SpacingCombiningMark:
  60.                    break; // Do nothing.
  61.                case UnicodeCategory.EnclosingMark:
  62.                    break; // Do nothing.
  63.  
  64.                default:
  65.                    sb.Append(c);
  66.                    break;
  67.            }
  68.        }
  69.  
  70.        return sb.ToString();
  71.  
  72.    }
  73.  
  74.    #endregion
  75.  
  76. }
  77.  
  78. // }
  79.  
  80. #endregion

VB.NET
Código
  1. ' ***********************************************************************
  2. ' Author   : Elektro
  3. ' Modified : 09-February-2016
  4. ' ***********************************************************************
  5.  
  6. #Region " Option Statements "
  7.  
  8. Option Strict On
  9. Option Explicit On
  10. Option Infer Off
  11.  
  12. #End Region
  13.  
  14. #Region " Imports "
  15.  
  16. Imports System.ComponentModel
  17. Imports System.Diagnostics
  18. Imports System.Globalization
  19. Imports System.Text
  20.  
  21. #End Region
  22.  
  23. #Region " String Extensions "
  24.  
  25. ' Namespace Text.Extensions.[String]
  26.  
  27. ''' ----------------------------------------------------------------------------------------------------
  28. ''' <summary>
  29. ''' Contains custom extension methods to use with the <see cref="System.String"/> type.
  30. ''' </summary>
  31. ''' ----------------------------------------------------------------------------------------------------
  32. <ImmutableObject(True)>
  33. <HideModuleName>
  34. Public Module Normalization
  35.  
  36. #Region " Public Extension Methods "
  37.  
  38.    ''' ----------------------------------------------------------------------------------------------------
  39.    ''' <summary>
  40.    ''' Transforms the diacritic characters in a Unicode string, into standard decomposited characters.
  41.    ''' </summary>
  42.    ''' ----------------------------------------------------------------------------------------------------
  43.    ''' <example> This is a code example.
  44.    ''' <code>
  45.    ''' Dim str As String = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics()
  46.    ''' Console.WriteLine(str) ' Result: "aeiou aeiou aeiou nN cC"
  47.    ''' </code>
  48.    ''' </example>
  49.    ''' ----------------------------------------------------------------------------------------------------
  50.    ''' <param name="sender">
  51.    ''' The source string.
  52.    ''' </param>
  53.    ''' ----------------------------------------------------------------------------------------------------
  54.    ''' <returns>
  55.    ''' The resulting normalized string.
  56.    ''' </returns>
  57.    ''' ----------------------------------------------------------------------------------------------------
  58.    <DebuggerStepThrough>
  59.    <Extension>
  60.    <EditorBrowsable(EditorBrowsableState.Advanced)>
  61.    Public Function NormalizeDiacritics(ByVal sender As String As String)
  62.  
  63.        Dim sb As New StringBuilder
  64.  
  65.        For Each c As Char In sender.Normalize(NormalizationForm.FormKD)
  66.  
  67.            Select Case CharUnicodeInfo.GetUnicodeCategory(c)
  68.  
  69.                Case UnicodeCategory.NonSpacingMark, UnicodeCategory.SpacingCombiningMark, UnicodeCategory.EnclosingMark
  70.                    ' Do nothing.
  71.                    Exit Select
  72.  
  73.                Case Else
  74.                    sb.Append(c)
  75.  
  76.            End Select
  77.  
  78.        Next c
  79.  
  80.        Return sb.ToString()
  81.  
  82.    End Function
  83.  
  84. #End Region
  85.  
  86. End Module
  87.  
  88. ' End Namespace
  89.  
  90. #End Region

Ejemplo de uso:

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

VB.NET
Código
  1. Dim str As String = ("áéíóú àèìòù äëïöü ñÑ çÇ").NormalizeDiacritics()
  2. 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


Título: Re: C# Quitar acentuación de String (Nueva duda)
Publicado por: 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.

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

Les paso la solución que terminé usando:

Código:
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]);
   }
}



Título: Re: C# Quitar acentuación de String (Nueva duda)
Publicado por: Eleкtro en 14 Julio 2017, 01:14 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
(http://www.fileformat.info/info/unicode/char/093e/devanagari_vowel_sign_aa.png)

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