比如我想匹配一个由m
ton
汉字组成的字符串,那么我可以使用:
[single Chinese character regular expression]{m,n}
是否存在单个汉字的正则表达式,可以是任何存在的汉字?
比如我想匹配一个由m
ton
汉字组成的字符串,那么我可以使用:
[single Chinese character regular expression]{m,n}
是否存在单个汉字的正则表达式,可以是任何存在的汉字?
匹配中文(好吧,CJK)字符的正则表达式是
\p{script=Han}
可以简单地理解为
\p{Han}
这假定您的正则表达式编译器满足UTS#18 Unicode 正则表达式中的RL1.2属性要求。Perl 和 Java 7 都符合该规范,但其他许多不符合。
在 Java 中,
\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}
在 C# 中
new Regex(@"\p{IsCJKUnifiedIdeographs}")
以下是来自维基百科的更多信息:CJK Unified Ideographs
名为 CJK Unified Ideographs (4E00–9FFF) 的基本块包含 U+4E00 到 U+9FEF 范围内的 20,976 个基本汉字。该块不仅包括中文书写系统中使用的字符,还包括日文书写系统中使用的汉字和在韩国使用正在减少的汉字。此块中的许多字符用于所有三种书写系统,而其他字符仅用于三种书写系统中的一种或两种。汉字也用于越南的 Nôm 脚本(现已过时)。
是否存在单个汉字的正则表达式,可以是任何存在的汉字?
推荐
要使用兼容 Flex 的词法分析器将模式与中文字符和其他 Unicode 代码点匹配,您可以使用向后兼容 Flex 的 C++的RE/flex 词法分析器。RE/flex 支持 Unicode 并与 Bison 一起构建词法分析器和解析器。
您可以在 RE/flex 规范中编写 Unicode 模式(和 UTF-8 正则表达式),例如:
%option flex unicode
%%
[肖晗] { printf ("xiaohan/2\n"); }
%%
使用 global%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()
for std::string
and std::wstring
)、size()
(或wsize()
对于宽字符长度)和echo()
. RE/flex 方法调用更简洁恕我直言,并且包括宽字符操作。
背景
在普通的旧 Flex 中,我最终为需要支持 Unicode 标识符的编译器项目定义了丑陋的 UTF-8 模式来捕获 ASCII 字母和 UTF-8 编码的字母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。
安全
在 Flex 模式中直接使用 UTF-8 时,有几个问题:
在 Flex 中编码您自己的 UTF-8 模式以匹配任何 Unicode 字符可能容易出错。模式应仅限于有效 Unicode 范围内的字符。Unicode 代码点覆盖范围从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF。U+D800 到 U+DFFF 的范围是为 UTF-16 代理对保留的,并且是无效的代码点。使用工具将 Unicode 范围转换为 UTF-8 时,请确保排除无效代码点。
要在词法分析器中捕获词法输入错误,需要一个特殊的.
(点)来匹配有效和无效的 Unicode,包括 UTF-8 溢出和无效字节序列,以便产生输入被拒绝的错误消息。如果您使用 dot 作为“catch-all-else”来生成错误消息,但您的 dot 与无效的 Unicode 不匹配,那么您的词法分析器将挂起(“扫描仪卡住”)或者您的词法分析器将在输出中 ECHO 垃圾字符由 Flex “默认规则”。
您的扫描仪应识别输入中的UTF BOM(Unicode 字节顺序标记)以切换到 UTF-8、UTF-16(LE 或 BE)或 UTF-32(LE 或 BE)。
正如您所指出的,诸如此类的模式[unicode characters]
根本不适用于 Flex,因为括号列表中的 UTF-8 字符是多字节字符,并且可以匹配每个单字节字符,但不能匹配 UTF-8 字符。
另请参阅RE/flex 用户指南中的无效 UTF 编码。
刚刚解决了一个类似的问题,
当您有太多要匹配的东西时,最好使用 anegated-set
并声明您不想匹配的内容,例如:
所有但不是数字:^[^0-9]*$
第二个^
将执行否定
在 Java 7 及更高版本中,格式应为:"\p{IsHan}"