Используйте регулярное выражение для соответствия любому китайскому символу в кодировке 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}"