Код для снятия диакритических меток с использованием ICU

Может ли кто-нибудь указать какой-нибудь примерный код, чтобы снять диакритические знаки (т.е. заменить символы с акцентами, умлауты и т.д. с их несогласованными, незанятыми и т.д. эквивалентами символов, например, каждый акцент é станет простой ASCII e) из UnicodeString с использованием библиотеки ICU в С++? Например:.

UnicodeString strip_diacritics( UnicodeString const &s ) {
    UnicodeString result;
    // ...
    return result;
}

Предположим, что s уже нормализовано. Спасибо.

Ответ 1

После дальнейшего поиска в другом месте:

UErrorCode status = U_ZERO_ERROR;
UnicodeString result;

// 's16' is the UTF-16 string to have diacritics removed
Normalizer::normalize( s16, UNORM_NFKD, 0, result, status );
if ( U_FAILURE( status ) )
  // complain

// code to convert UTF-16 's16' to UTF-8 std::string 's8' elided

string buf8;
buf8.reserve( s8.length() );
for ( string::const_iterator i = s8.begin(); i != s8.end(); ++i ) {
  char const c = *i;
  if ( isascii( c ) )
    buf8.push_back( c );
}
// result is in buf8

который является O (n).

Ответ 2

ICU позволяет транслитерировать строку с использованием определенного правила. Мое правило NFD; [:M:] Remove; NFC: декомпозиция, удаление диакритики, перекомпоновка. Следующий код принимает UTF-8 std::string в качестве ввода и возвращает другой UTF-8 std::string:

#include <unicode/utypes.h>
#include <unicode/unistr.h>
#include <unicode/translit.h>

std::string desaxUTF8(const std::string& str) {
    // UTF-8 std::string -> UTF-16 UnicodeString
    UnicodeString source = UnicodeString::fromUTF8(StringPiece(str));

    // Transliterate UTF-16 UnicodeString
    UErrorCode status = U_ZERO_ERROR;
    Transliterator *accentsConverter = Transliterator::createInstance(
        "NFD; [:M:] Remove; NFC", UTRANS_FORWARD, status);
    accentsConverter->transliterate(source);
    // TODO: handle errors with status

    // UTF-16 UnicodeString -> UTF-8 std::string
    std::string result;
    source.toUTF8String(result);

    return result;
}