Используйте регулярное выражение для соответствия любому китайскому символу в кодировке utf-8

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

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

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

Ответ 1

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

\p{script=Han}

который можно просто заменить

\p{Han}

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

Ответ 2

В Java,

\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}

Ответ 3

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

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

Чтобы сопоставить шаблоны с китайскими символами и другими кодовыми точками Юникода с помощью лексического анализатора, совместимого с Flex, вы можете использовать RE/flex лексический анализатор для С++, который обратно совместим с Flex. RE/flex поддерживает Unicode и работает с Bison для создания лексеров и парсеров.

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

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

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

Фон

В простой старой 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 overlong characters в некоторых случаях, которые недействительны UTF-8. Если вы думаете об этом подходе, то будьте осторожны в отношении проблем и проблем безопасности. Вместо этого используйте генератор сканера, совместимый с Unicode, например RE/flex.

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

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

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

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

  • Чтобы ловить лексические ошибки ввода в вашем лексере, потребуется специальная . (точка), которая соответствует допустимому и недопустимому Unicode, включая перерасход UTF-8 и недопустимые последовательности байтов, чтобы создать сообщение об ошибке вход отклонен. Если вы используете точку "catch-all-else" для создания сообщения об ошибке, но ваша точка не соответствует недопустимому Unicode, тогда вы будете лексер будет зависать ( "застрял сканер" ), или ваш лексер будет отображать символы ECHO на выходе по правилу Flex по умолчанию.

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

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

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

Ответ 4

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