Используйте регулярное выражение для сопоставления ЛЮБОГО китайского символа в кодировке utf-8 - PullRequest
23 голосов
/ 06 марта 2012

Например, я хочу сопоставить строку, состоящую из m до n китайских символов, тогда я могу использовать:

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

Существует ли какое-либо регулярное выражение одного китайского символа, которым могут быть любые китайские символы?

Ответы [ 4 ]

27 голосов
/ 06 марта 2012

Регулярное выражение для соответствия китайскому (ну, CJK) символу -

\p{script=Han}

, которое можно просто обозначить

\p{Han}

Предполагается, что ваш компилятор регулярных выражений соответствует требованию RL1.2 Свойства из UTS # 18 Регулярные выражения Unicode . Perl и Java 7 оба соответствуют этой спецификации, но многие другие не соответствуют.

6 голосов
/ 04 июня 2014

В Java

\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}
2 голосов
/ 02 марта 2016

Существует ли какое-либо регулярное выражение одного китайского символа, которым могут быть любые существующие китайские символы?

Рекомендация

Для соответствияшаблоны с китайскими символами и другими кодовыми точками Unicode с Flex-совместимым лексическим анализатором, вы можете использовать RE / flex lexical analyzer для C ++, который обратно совместим с Flex.RE / flex поддерживает Unicode и работает с Bison для создания лексеров и анализаторов.

Вы можете писать шаблоны Unicode (и регулярные выражения UTF-8) в спецификациях RE / flex, таких как:

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

Используйте глобальный %option unicode для включения Unicode.Вы также можете использовать локальный модификатор (?u:), чтобы ограничить Юникод одним шаблоном (так что все остальное по-прежнему ASCII / 8-битное, как в 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]); }
%%

Опция flex обеспечивает совместимость с Flex,так что вы можете использовать yytext, yyleng, ECHO и так далее.Без опции flex RE / flex ожидает вызовы методов Lexer: text() (или str() и wstr() для std::string и std::wstring), size() (или wsize() для широкой длины символа),и echo().Вызовы методов RE / flex более чистые ИМХО и включают операции с широкими символами.

Фон

В простом старом Flex я в итоге определил уродливые шаблоны UTF-8 для захвата ASCIIбуквы и буквы в кодировке UTF-8 для проекта компилятора, который требовал поддержки идентификаторов 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})*            

Шаблон alpha поддерживает буквы ASCII, символы подчеркивания и кодовые точки Unicode, которые используются в идентификаторах(\p{L} и т. Д.).Шаблон допускает больше кодовых точек Unicode, чем это абсолютно необходимо, чтобы поддерживать размер этого шаблона управляемым, поэтому он торгует компактностью за некоторую нехватку точности и позволяет UTF-8 сверхдлинные символы в некоторых случаях, которые не являются допустимыми UTF-8.Если вы думаете об этом подходе, будьте осторожны с проблемами и проблемами безопасности.Вместо этого используйте генератор сканера с поддержкой Unicode, например RE / flex .

Безопасность

При использовании UTF-8 непосредственно в шаблонах Flex,Есть несколько проблем:

  1. Кодирование ваших собственных шаблонов UTF-8 во Flex для соответствия любому символу Unicode может быть подвержено ошибкам.Шаблоны должны быть ограничены символами только в допустимом диапазоне Юникода.Кодовые точки Unicode охватывают диапазон от U + 0000 до U + D7FF и от U + E000 до U + 10FFFF.Диапазон от U + D800 до U + DFFF зарезервирован для суррогатных пар UTF-16 и составляет недопустимых кодовых точек .При использовании инструмента для преобразования диапазона Unicode в UTF-8 убедитесь, что исключены недопустимые кодовые точки.

  2. Шаблоны должны отклонять overlong и другие недопустимыепоследовательности байтов .Неверный UTF-8 не должен приниматься в режиме без вывода сообщений.

  3. Для обнаружения лексических ошибок ввода в вашем лексере потребуется специальный . (точка), который соответствует действительному и недействительному Unicode, включая UTF-8 переполнений и недопустимых байтовых последовательностей, чтобы создать сообщение об ошибке, что ввод отклонен.Если вы используете точку в качестве «поймать все остальное» для создания сообщения об ошибке, но ваша точка не соответствует недействительному Unicode, то вы повредите лексер («сканер замят») или ваш лексер будет выводить мусорные символы ECHO на выходепо гибкому «правилу по умолчанию».

  4. Ваш сканер должен распознавать UTF BOM (метка порядка байтов Unicode) на входе для переключения на UTF-8, UTF-16 (LE или BE) или UTF-32 (LE или BE).

  5. Как вы отметили, такие шаблоны, как [unicode characters], вообще не работают с Flex, поскольку UTF-8 символов в списке в скобках являются многобайтовыми символами, и каждому отдельному байтовому символу может соответствовать, но не символ UTF-8.

См. Также недопустимые кодировки UTF вRE / flex руководство пользователя.

0 голосов
/ 20 апреля 2015

В Java 7 и выше формат должен быть следующим: "\ p {IsHan}"

...