2014-06-30 15 views
8

Proste pytanie: mieć std::string, określić, które z jego znaków to cyfry, symbole, białe spacje itp. W odniesieniu do języka użytkownika i ustawień regionalnych (locale).Klasyfikacja znaków

udało mi się podzielić ciąg na zestaw znaków przy użyciu boost locale boundary analysis tool:

std::string text = u8"生きるか死ぬか"; 

boost::locale::boundary::segment_index<std::string::const_iterator> characters(
    boost::locale::boundary::character, 
    text.begin(), text.end(), 
    boost::locale::generator()("ja_JP.UTF-8")); 

for (const auto& ch : characters) { 
    // each 'ch' is a single character in japanese language 
} 

Ja jednak dalej nie widzę żadnego sposobu określenia czy ch jest cyfrą lub symbolem, czy cokolwiek innego. Istnieją boost string classification algorithms, ale te wydają się nie działać z .. niezależnie od *segment_index::iterator jest.

Nie mogę również zastosować std::isalpha(std::locale), ponieważ nie jestem pewien, czy możliwe jest przekonwertowanie segmentu zwiększenia na char lub wchar_t.

Czy istnieje jakiś sposób na klasyfikację symboli?

+2

Jak zwykle: ci, którzy głosują: dlaczego? Co jest nie tak z pytaniem? Czy na pewno znasz poprawną odpowiedź? – Ixanezis

+0

Jeśli się nie mylę, typ 'ch' to' segment ', a segment jest tworzony przez parę iteratorów. Tak więc 'ch' zawiera parę iteratora na' tekście', aby ograniczyć znak. Ponieważ funkcje klasyfikują wymaga tylko wartości 'char_type' i używasz znaków wielobajtowych, możesz przekonwertować każdy segment w ciągu widechar tylko jednego znaku (jeśli nie jest on zastępowany w łańcuchu), a następnie użyć funkcji klasyfikuj. Ma sens? – Gonmator

+0

@Gonmator: Jeśli ci się udało, sugerujesz przekonwertować 'std :: string' na' std :: wstring' i użyć dowolnego 'isdigit (str [0])', zakładając, że 'str [0 ] 'teraz oznacza pojedynczą szeroką postać. Jeśli się nie mylę, zwiększa to tylko szansę na poprawne działanie kodu, ale nadal istnieją symbole, których nie można przedstawić za pomocą pojedynczego 'wchar_t', np. w "שָלוֹם". Jeśli polegam na tym, mogę zapomnieć o analizie granicy wzmocnienia i po prostu zawsze używam 'str [0]', jeśli 'str' jest szerokim ciągiem znaków. – Ixanezis

Odpowiedz

3

Istnieje szereg funkcji i obiektów wspierających ten w <locale> ale ... Przykładowy tekst dasz wygląda jak UTF-8, który jest kodowania wielobajtowego, a funkcje w <locale> nie pracować wielobajtowe kodowania.

Proponuję uzyskać bibliotekę ICU i użyć jej. Pośród innych rzeczy, , umożliwia testowanie wszystkich właściwości zdefiniowanych w bazie danych znaków Unicode. Ma również makra lub funkcje do iteracji przez ciąg (lub co najmniej tablicę z char), wyodrębniając jeden punkt kodowy UTF_32 w tym samym czasie (który jest, co chcesz przetestować).

+0

Dzięki. Myślałem o tym, że 'boost :: locale' w jakiś sposób zapewnia funkcjonalność, której szukam, ponieważ domyślnie używa ICU wewnątrz. I więcej, nie jestem pewien, że wyodrębnianie pojedynczego codepoint UTF32 jest tym, czego szukam, ponieważ jak stwierdza biblioteka doładowania, istnieją symbole złożone z kilku różnych punktów kodowych UTF32, takich jak שָ – Ixanezis