例如,我想匹配一个由m
到n
个汉字组成的字符串,然后我可以使用:
[single Chinese character regular expression]{m,n}
是否存在单个汉字的正则表达式,可能是存在的任何汉字?
答案 0 :(得分:26)
匹配中文(好吧,CJK)角色的正则表达式是
\p{script=Han}
可以简单地用于
\p{Han}
这假设您的正则表达式编译器符合requirement RL1.2 Properties from UTS#18 Unicode Regular Expressions。 Perl和Java 7都符合该规范,但许多其他规则都没有。
答案 1 :(得分:6)
在Java中,
\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}
答案 2 :(得分:2)
是否存在单个汉字的正则表达式,可能是存在的任何汉字?
<强>建议强>
要将模式与中文字符和其他Unicode代码点与Flex兼容的词法分析器匹配,您可以使用RE/flex lexical analyzer用于向后兼容Flex的C ++。 RE / flex支持Unicode,并与Bison一起构建词法分析器和解析器。
您可以在RE / flex规范中编写Unicode模式(和UTF-8正则表达式),例如:
%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
),{{ 1}}(或size()
表示宽字符长度)和wsize()
。 RE / flex方法调用是更清晰的恕我直言,并包括宽字符操作。
<强>背景强>
在普通的Flex中,我最终定义了丑陋的UTF-8模式,以便为需要支持Unicode标识符的编译器项目捕获ASCII字母和UTF-8编码字母echo()
:
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代码点。该模式允许更多的Unicode代码点,而不是绝对必要的,以保持这种模式的大小可管理,因此它在一些缺乏准确性的情况下交易紧凑性,并且在某些无效UTF-8的情况下允许UTF-8 overlong characters。如果您正在考虑这种方法而不是对问题和安全问题保持警惕。请使用支持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代理对,并且是invalid code points。使用工具将Unicode范围转换为UTF-8时,请确保排除无效的代码点。
模式应拒绝overlong和其他invalid byte sequences。不应无声地接受无效的UTF-8。
要捕获词法分析器中的词汇输入错误,需要一个特殊的\p{L}
(点)来匹配有效和无效的Unicode,包括UTF-8溢出和无效的字节序列,以便产生错误消息输入被拒绝。如果你使用dot作为&#34; catch-all-else&#34;要生成错误消息,但你的点与无效的Unicode不匹配,那么你的词法分析器将挂起(&#34;扫描仪被卡住&#34;)或者你的词法分析器会在输出上的ECHO垃圾字符由Flex&#34;默认规则&#34;
您的扫描仪应识别输入中的UTF BOM(Unicode字节顺序标记),以切换为UTF-8,UTF-16(LE或BE)或UTF-32(LE或BE)
正如您所指出的那样,.
等模式根本不适用于Flex,因为括号列表中的UTF-8字符是多字节字符,每个单字节字符可以匹配但不能匹配UTF -8个字符。
另请参阅RE / flex用户指南中的invalid UTF encodings。
答案 3 :(得分:1)
在C#中
new Regex(@"\p{IsCJKUnifiedIdeographs}")
这是来自维基百科的更多信息:CJK Unified Ideographs
名为CJK统一表意文字(4E00–9FFF)的基本块包含20,976个基本汉字,范围从U + 4E00到U + 9FEF。该块不仅包含中文书写系统中使用的字符,而且还包含日语书写系统中使用的汉字和汉字,而汉字在韩国逐渐减少。该块中的许多字符都在所有三个书写系统中使用,而其他字符仅在三个书写系统中的一两个中使用。越南的Nôm文字(现在已经过时)中也使用了汉字。
答案 4 :(得分:0)
刚刚解决了一个类似的问题,
当你有太多东西要匹配时,最好使用 negated-set
并声明你不想匹配的内容:
所有但不是数字:^[^0-9]*$
第二个 ^
将实现否定
答案 5 :(得分:-2)
在Java 7及更高版本中,格式应为:&#34; \ p {IsHan}&#34;