2012-09-05 6 views
6

Chcę usunąć akcenty i bardziej ogólnie znaki diakrytyczne z ciągu, aby zainicjować wyszukiwanie niewrażliwe na akcent. podstawie jakiegoś czytania w klasach znaków Unicode, mam wymyślić to:Usuwanie akcentów z QStringa

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; 
} 

Wydaje się dość dobrze pracować dla języków opartych na alfabecie łacińskim, ale zastanawiam się o jego adekwatności w innych alfabetów: arabski , cyrylica, CJK ... którego nie mogę przetestować z powodu braku zrozumienia kulturowego.

Konkretnie Chciałbym wiem:

  1. Jaką formę normalizacji Unicode lepiej nadaje się do tego problemu: NormalizationForm_KD lub NormalizationForm_D?
  2. Czy wystarczy usunąć znaki należące do kategorii Mark_NonSpacing i , czy powinna ona zawierać więcej kategorii?
  3. Czy są inne ulepszenia powyższego kodu, które sprawią, że będzie działać jak najlepiej dla wszystkich języków?
+1

sposób chcą Państwo również 'QChar :: Mark_Enclosing' –

+0

kwestia NFD vs NFKD jest coś trzeba zdecydować, na podstawie tego, co staramy się robić. Zobacz "Figure 6" [Unicode Normalization Forms] [1], aby zdecydować, czy chcesz rozłożyć postać w tym zakresie. Podejrzewam, że chcesz NFD. –

+0

@Dave: Zakładam, że [1] był: http://www.unicode.org/reports/tr15/ –

Odpowiedz

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

Ten kod jest zbyt obdzierany. Cyfry, znaki interpunkcyjne i znaki nieakcentowane poza alfabetem łacińskim muszą być zachowane, a kod ten usuwa je. Wszystko z wyjątkiem znaków diakrytycznych musi być zachowane. –