2012-09-05 20 views
6

Quiero eliminar los acentos y, en general, las marcas diacríticas de una cadena para iniciar una búsqueda insensible al acento. Sobre la base de un poco de lectura en las clases de caracteres Unicode, se me ha ocurrido con esto:Eliminar acentos de un QString

QString unaccent(const QString s) 
{ 
    QString s2 = s.normalized(QString::NormalizationForm_D); 
    QString out; 
    for (int i=0,j=s2.length(); i<j; i++) 
    { 
    // strip diacritic marks 
    if (s2.at(i).category()!=QChar::Mark_NonSpacing && 
     s2.at(i).category()!=QChar::Mark_SpacingCombining) 
    { 
      out.append(s2.at(i)); 
    } 
    } 
    return out; 
} 

Parece que funciona razonablemente bien para idiomas latinos, pero me pregunto acerca de su idoneidad en otros alfabetos: árabe , cirílico, CJK ... que no puedo probar debido a la falta de comprensión cultural de estos.

Específicamente Me hubiera gustado saber:

  1. ¿Qué forma de normalización Unicode es más adecuado para este problema: NormalizationForm_KD o NormalizationForm_D?
  2. ¿Es suficiente eliminar los caracteres que pertenecen a las categorías Mark_NonSpacing y Mark_SpacingCombining o debe incluir más categorías?
  3. ¿Existen otras mejoras en el código anterior que lo hagan funcionar lo mejor posible para todos los idiomas?
+1

usted manera también quieren 'QChar :: Mark_Enclosing' –

+0

La cuestión de NFD vs NFKD es algo que necesita para decidir sobre la base de lo que está tratando de hacer. Consulte "Figura 6" de [Formas de normalización Unicode] [1] para decidir si desea descomponer un carácter en esa medida. Sospecho que quieres NFD. –

+0

@Dave: Supongo que [1] fue: http://www.unicode.org/reports/tr15/ –

Respuesta

0
QString unaccent(const QString s) 
{ 
    QString output(s.normalized(QString::NormalizationForm_D)); 
    return output.replace(QRegExp("[^a-zA-Z\\s]"), ""); 
} 
+2

Este código se quita demasiado. Los dígitos, los signos de puntuación y los caracteres no acentuados fuera del alfabeto latino deben conservarse, mientras que este código los elimina. Cualquier cosa que no sean signos diacríticos debe mantenerse. –