Есть ли регулярное выражение одного китайского символа, который может быть любым китайским символом, который существует?
blockquote>Рекомендация
Чтобы сопоставить шаблоны с китайскими символов и других кодов Unicode с помощью лексического анализатора, совместимого с Flex, вы можете использовать лексический анализатор RE / flex для C ++, который обратно совместим с 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()
для широкой длины символа) иecho()
. Вызов метода RE / flex является более чистым IMHO и включает в себя операции с широким символом.Фон
В обычном старом 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 существует несколько проблемы:
- Кодирование собственных шаблонов 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.
- Чтобы ловить лексические ошибки ввода в вашем лексере, потребуется специальная
.
(точка), которая соответствует допустимому и недопустимому Юникоду, включая перерасход 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.