Pytanie Użyj wyrażenia regularnego, aby dopasować KAŻDĄ chińską postać w kodowaniu utf-8


Na przykład chcę dopasować ciąg składający się z m do n Chińskie znaki, wtedy mogę użyć:

[single Chinese character regular expression]{m,n}

Czy istnieje jakiś regularny wyraz jednego chińskiego znaku, który może być dowolnym chińskim znakiem, który istnieje?


21
2018-03-06 00:53


pochodzenie


Przynajmniej proszę podać informacje na temat silnika regex, którego używasz. - Kevin Ballard
@ KevinBallard Nie jestem do końca pewien, którego silnika używam. Wiem, że używam funkcji wyrażenia regularnego w flex(lexer) - xiaohan2012
Możliwy duplikat Jak zrobić flex (skaner leksykalny), aby odczytać wejście znaków UTF-8? - Thomas Dickey
Flex tego nie zrobi; odpowiedzi, które zakładają, że nie odpowiadają na pytanie. - Thomas Dickey


Odpowiedzi:


Wyrażenie regularne odpowiadające chińskiej (dobrze, CJK) jest

\p{script=Han}

które można łatwo sprowadzić

\p{Han}

Zakłada to, że kompilator regex spełnia wymaganie RL1.2 Właściwości z UTS # 18 Wyrażenia regularne Unicode. Perl i Java 7 spełniają tę specyfikację, ale wiele innych nie.


23
2018-03-06 00:56



Szkoda, że ​​Flex nie wydaje się go wspierać. Dzięki i tak. - xiaohan2012
@ Xiaohan2012: Nie sądzę, że Flex naprawdę w ogóle obsługuje kodowanie Unicode - Kevin Ballard
@ xiaohan2012 Gdybym był tobą, chciałbym przyjrzeć się użyciu niektórych narzędzi do analizowania i analizowania dostępnych pod Perl lub Java, które obsługują Unicode. - tchrist
Czy istnieje wariant tego dla C # - tofutim
To daje Unknown character property name {Han} dla Java-8. Co jest nie tak? - Andremoniy


W języku Java,

\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}

6
2018-06-04 03:20



Zauważ, że to tylko znajduje znaki w bloku z U + 4E00-U + 9FFF. Nie znaleziono wszystkich chińskich znaków, które istnieją. - martin
Pytanie jest oznaczone tagiem Flex dla języka C i C ++, który nie obsługuje języka \p{C} blok znaków. - Dr. Alex RE


Czy istnieje jakiś regularny wyraz jednego chińskiego znaku, który może być dowolnym chińskim znakiem, który istnieje?

Zalecenie

Aby dopasować wzorce z chińskimi znakami i innymi kodami Unicode za pomocą analizatora leksykalnego zgodnego z Flex, możesz użyć skrótu RE / flex leksykalny analizator dla C ++, który jest wstecznie kompatybilny z Flex. RE / flex obsługuje Unicode i współpracuje z Bizonem, aby budować lexery i parsery.

Możesz pisać wzorce Unicode (i wyrażenia regularne UTF-8) w specyfikacjach RE / flex, takich jak:

%option flex unicode
%%
[肖晗]   { printf ("xiaohan/2\n"); }
%%

Użyj globalnego %option unicode aby włączyć Unicode. Można również użyć modyfikatora lokalnego (?u:) aby ograniczyć kodowanie Unicode do jednego wzorca (więc wszystko inne nadal jest ASCII / 8-bitowe jak w Flex):

%option flex
%%
(?u:[肖晗])   { printf ("xiaohan/2\n"); }
(?u:\p{Han})  { printf ("Han character %s\n", yytext); }
.             { printf ("8-bit character %d\n", yytext[0]); }
%%

Opcja flex włącza kompatybilność Flex, dzięki czemu możesz z niego korzystać yytext, yyleng, ECHO, i tak dalej. Bez flex opcja RE / flex oczekuje wywołań metod Lexer: text() (lub str() i wstr() dla std::string i std::wstring), size() (lub wsize() dla szerokiej długości znaku), i echo(). Wywołania metod RE / flex są czystsze IMHO i obejmują szerokie operacje char.

tło

W prostym starym Flexie skończyłem definiowanie brzydkich wzorów UTF-8 do przechwytywania liter ASCII i liter zakodowanych w UTF-8 dla projektu kompilatora wymagającego obsługi identyfikatorów Unicode id:

digit           [0-9]
alpha           ([a-zA-Z_\xA8\xAA\xAD\xAF\xB2\xB5\xB7\xB8\xB9\xBA\xBC\xBD\xBE]|[\xC0-\xFF][\x80-\xBF]*|\\u([0-9a-fA-F]{4}))
id              ({alpha})({alpha}|{digit})*            

The alpha wzorzec obsługuje litery ASCII, podkreślenia i kody Unicode używane w identyfikatorach (\p{L} itp). Wzorzec pozwala uzyskać więcej punktów kodowych Unicode, niż jest to absolutnie konieczne, aby rozmiar tego wzoru był łatwy w zarządzaniu, więc zajmuje się zwartością z pewnym brakiem dokładności i pozwala na UTF-8 nadmierne postacie w niektórych przypadkach niepoprawne UTF-8. Jeśli myślisz o tym podejściu, to bądź ostrożny w kwestii problemów i bezpieczeństwa. Zamiast tego użyj generatora skanerów z obsługą Unicode, na przykład Odruch.

Bezpieczeństwo

Podczas korzystania z UTF-8 bezpośrednio w wzorach Flex, istnieje kilka problemów:

  1. Kodowanie własnych wzorów UTF-8 w programie Flex w celu dopasowania znaków Unicode może być podatne na błędy. Wzory powinny być ograniczone wyłącznie do znaków z ważnego zakresu Unicode. Punkty kodu Unicode obejmują zakres od U + 0000 do U + D7FF i U + E000 do U + 10FFFF. Zakres U + D800 do U + DFFF jest zarezerwowany dla par zastępczych UTF-16 i jest nieprawidłowe punkty kodowe. Gdy używasz narzędzia do konwersji zakresu kodu Unicode na UTF-8, upewnij się, że wykluczasz nieprawidłowe punkty kodowe.

  2. Wzory powinny odrzucić wydłużony i inne niepoprawne sekwencje bajtów. Nieprawidłowy koder UTF-8 nie powinien być cicho akceptowany.

  3. Aby złapać leksykalne błędne dane wejściowe w twoim lexierze będzie wymagało specjalnego . (kropka), która pasuje do prawidłowego i nieprawidłowego kodu Unicode, w tym przekroczeń UTF-8 i niepoprawnych sekwencji bajtów, w celu wygenerowania komunikatu o błędzie, że dane wejściowe zostały odrzucone. Jeśli użyjesz kropki jako "catch-all-else" do wygenerowania komunikatu o błędzie, ale twoja kropka nie pasuje do nieprawidłowego Unicode, to twój lexer zawiesza się ("skaner jest zacięty") lub twój lexer będzie znakami śmieci ECHO na wyjściu według reguły domyślnej Flex ".

  4. Twój skaner powinien rozpoznać UTF BOM (Unicode Byte Order Mark) na wejściu, aby przejść do UTF-8, UTF-16 (LE lub BE) lub UTF-32 (LE lub BE).

  5. Jak zauważysz, wzorce takie jak [unicode characters] w ogóle nie działają z Flex, ponieważ znaki UTF-8 w liście nawiasów są znakami wielobajtowymi i każdy znak jednobajtowy może być dopasowany, ale nie znak UTF-8.

Zobacz też nieprawidłowe kodowanie UTF w przewodniku użytkownika RE / Flex.


0
2018-03-02 16:26





W języku Java 7 i nowszych format powinien wyglądać następująco: "\ p {IsHan}"


-2
2018-04-20 10:03



w rzeczywistości historia edycji pokazuje, że ty też napisałeś InHan, @Robert tylko dodał formatowanie, więc wyrażenie pojawia się w sposób ciągły - Zoltán
Wskazówka: możesz wybierać edytować samemu, aby poprawić swój błąd. ;-) - Robert
Pytanie jednak nie pyta, jak to zrobić w Javie. Pytanie jest oznaczone jako "flex-lexer". - hvd