40

比如我想匹配一个由mton汉字组成的字符串,那么我可以使用:

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

是否存在单个汉字的正则表达式,可以是任何存在的汉字?

4

6 回答 6

40

匹配中文(好吧,CJK)字符的正则表达式是

\p{script=Han}

可以简单地理解为

\p{Han}

这假定您的正则表达式编译器满足UTS#18 Unicode 正则表达式中的RL1.2属性要求。Perl 和 Java 7 都符合该规范,但其他许多不符合。

于 2012-03-06T00:56:44.540 回答
7

在 Java 中,

\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}
于 2014-06-04T03:20:24.360 回答
3

在 C# 中

new Regex(@"\p{IsCJKUnifiedIdeographs}")

这是在Microsoft 文档中

以下是来自维基百科的更多信息:CJK Unified Ideographs

名为 CJK Unified Ideographs (4E00–9FFF) 的基本块包含 U+4E00 到 U+9FEF 范围内的 20,976 个基本汉字。该块不仅包括中文书写系统中使用的字符,还包括日文书写系统中使用的汉字和在韩国使用正在减少的汉字。此块中的许多字符用于所有三种书写系统,而其他字符仅用于三种书写系统中的一种或两种。汉字也用于越南的 Nôm 脚本(现已过时)。

于 2020-02-11T11:25:05.783 回答
2

是否存在单个汉字的正则表达式,可以是任何存在的汉字?

推荐

要使用兼容 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 兼容性,因此您可以使用yytextyylengECHO等。如果没有flex选项 RE/flex 期望 Lexer 方法调用:(text()str()wstr()for std::stringand 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 时,有几个问题:

  1. 在 Flex 中编码您自己的 UTF-8 模式以匹配任何 Unicode 字符可能容易出错。模式应仅限于有效 Unicode 范围内的字符。Unicode 代码点覆盖范围从 U+0000 到 U+D7FF 和 U+E000 到 U+10FFFF。U+D800 到 U+DFFF 的范围是为 UTF-16 代理对保留的,并且是无效的代码点。使用工具将 Unicode 范围转换为 UTF-8 时,请确保排除无效代码点。

  2. 模式应该拒绝过长和其他无效的字节序列。不应默默接受无效的 UTF-8。

  3. 要在词法分析器中捕获词法输入错误,需要一个特殊的.(点)来匹配有效和无效的 Unicode,包括 UTF-8 溢出和无效字节序列,以便产生输入被拒绝的错误消息。如果您使用 dot 作为“catch-all-else”来生成错误消息,但您的 dot 与无效的 Unicode 不匹配,那么您的词法分析器将挂起(“扫描仪卡住”)或者您的词法分析器将在输出中 ECHO 垃圾字符由 Flex “默认规则”。

  4. 您的扫描仪应识别输入中的UTF BOM(Unicode 字节顺序标记)以切换到 UTF-8、UTF-16(LE 或 BE)或 UTF-32(LE 或 BE)。

  5. 正如您所指出的,诸如此类的模式[unicode characters]根本不适用于 Flex,因为括号列表中的 UTF-8 字符是多字节字符,并且可以匹配每个单字节字符,但不能匹配 UTF-8 字符。

另请参阅RE/flex 用户指南中的无效 UTF 编码

于 2016-03-02T16:26:10.557 回答
1

刚刚解决了一个类似的问题,

当您有太多要匹配的东西时,最好使用 anegated-set并声明您不想匹配的内容,例如:

所有但不是数字:^[^0-9]*$

第二个^将执行否定

于 2021-01-19T11:12:23.097 回答
-1

在 Java 7 及更高版本中,格式应为:"\p{IsHan}"

于 2015-04-20T10:03:25.883 回答