例如,我想匹配一个由m到n中文字符组成的字符串,那么我可以用途:
m
n
[single Chinese character regular expression]{m,n}
是否存在单个汉字的正则表达式,它可以是任何存在的汉字?
epggiuax1#
匹配一个中文(CJK)字符的正则表达式是
\p{script=Han}
可以简单地认为
\p{Han}
这里假设你的正则表达式编译器满足RL1.2UTS#18中的属性**Unicode正则表达式 * 的要求。Perl和Java 7都满足这个规范,但其他很多都不满足。
hi3rlvi22#
在Java中
\p{InCJK_UNIFIED_IDEOGRAPHS}{1,3}
w80xi6nr3#
在C#中
new Regex(@"\p{IsCJKUnifiedIdeographs}")
这是在微软文档中以下是来自Wikipedia的更多信息:CJK Unified Ideographs基本块命名为中日韩统一表意文字(4 E00 - 9 FFF)包含U+4 E00到U+9 FEF范围内的20,976个基本汉字。该块不仅包括中文书写系统中使用的字符,还包括日语书写系统中使用的汉字和在韩国使用的汉字,后者在韩国的使用正在减少。该块中的许多字符在所有三种书写系统中使用。而其他的则只在三种文字中的一种或两种中使用。越南的Nôm文字也使用汉字(现已过时)。
l0oc07j24#
推荐
要使用Flex兼容的词法分析器将模式与中文字符和其他Unicode代码点匹配,可以使用与Flex向后兼容的RE/flex lexical analyzer for C++。RE/flex支持Unicode,并与野牛一起构建词法分析器和解析器。您可以在RE/flex规范中编写Unicode模式(和UTF-8正则表达式),例如:
%option flex unicode %% [肖晗] { printf ("xiaohan/2\n"); } %%
使用全局%option unicode来启用Unicode。您还可以使用局部修饰符(?u:)将Unicode限制为单个模式(因此其他内容仍然是ASCII/8位,如Flex中所示):
%option unicode
(?u:)
%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()(对于std::string和std::wstring,或者str()和wstr())、size()(对于宽字符长度,或者wsize())和echo()。RE/flex方法调用是更干净的IMHO,并且包括宽字符操作。
flex
yytext
yyleng
ECHO
text()
std::string
std::wstring
str()
wstr()
size()
wsize()
echo()
背景
在普通的老Flex中,我最终定义了丑陋的UTF-8模式来捕获ASCII字母和UTF-8编码的字母,用于需要支持Unicode标识符id的编译器项目:
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。
alpha
\p{L}
安全性
在Flex模式中直接使用UTF-8时,有几个问题:1.在Flex中编码您自己的UTF-8模式以匹配任何Unicode字符可能容易出错。模式应仅限于有效Unicode范围内的字符。Unicode代码点涵盖范围U+0000到U+ D 7 FF和U+E000到U+10 FFFF。范围U+D800到U+DFFF是为UTF-16代理对保留的,并且是无效代码点。使用工具将Unicode范围转换为UTF-8时,请确保排除无效的代码点。1.模式应该拒绝过长的和其他无效的字节序列。无效的UTF-8不应该被默认接受。1.要在lexer中捕获词法输入错误,需要一个特殊的.(dot)匹配有效和无效的Unicode,包括UTF-8溢出和无效的字节序列,以便产生输入被拒绝的错误消息。如果您使用dot作为“catch-all-else”来产生错误消息,但您的dot不匹配无效的Unicode,那么你的lexer将挂起(“scanner is camming”)或者你的lexer将在Flex的“default rule”输出中显示垃圾字符。1.您的扫描仪应识别输入中的UTF BOM(Unicode字节顺序标记),以切换到UTF-8、UTF-16(LE或BE)或UTF-32(LE或BE)。1.正如您所指出的,像[unicode characters]这样的模式在Flex中根本不起作用,因为方括号列表中的UTF-8字符是多字节字符,每个单字节字符都可以匹配,但不能匹配UTF-8字符。另请参阅RE/flex用户指南中的无效UTF编码。
.
[unicode characters]
e0uiprwp5#
\u4E00-\u9FFF
如果你的语言在其他答案中不支持像{Han}/{script=Han}/{IsCJKUnifiedIdeographs}这样的符号,这很有用。注:这对应于CJK Unified Ideographs,并包括其他语言,如韩语,日语和越南语。
{Han}
{script=Han}
{IsCJKUnifiedIdeographs}
blpfk2vs6#
在Java 7和更高版本中,格式应该是:“\p{IsHan}”
gstyhher7#
刚刚解决了一个类似的问题当你有太多的东西要匹配时,最好使用negated-set并声明你不想匹配的东西:所有但不是数字:^[^0-9]*$第二个^将实现否定
negated-set
^[^0-9]*$
^
u4dcyp6a8#
就像这样
package main import ( "fmt" "regexp" ) func main() { compile, err := regexp.Compile("\\p{Han}") // match one any Chinese character if err != nil { return } str := compile.FindString("hello 世界") fmt.Println(str) // output: 世 }
8条答案
按热度按时间epggiuax1#
匹配一个中文(CJK)字符的正则表达式是
可以简单地认为
这里假设你的正则表达式编译器满足RL1.2UTS#18中的属性**Unicode正则表达式 * 的要求。Perl和Java 7都满足这个规范,但其他很多都不满足。
hi3rlvi22#
在Java中
w80xi6nr3#
在C#中
这是在微软文档中
以下是来自Wikipedia的更多信息:CJK Unified Ideographs
基本块命名为中日韩统一表意文字(4 E00 - 9 FFF)包含U+4 E00到U+9 FEF范围内的20,976个基本汉字。该块不仅包括中文书写系统中使用的字符,还包括日语书写系统中使用的汉字和在韩国使用的汉字,后者在韩国的使用正在减少。该块中的许多字符在所有三种书写系统中使用。而其他的则只在三种文字中的一种或两种中使用。越南的Nôm文字也使用汉字(现已过时)。
l0oc07j24#
是否存在单个汉字的正则表达式,它可以是任何存在的汉字?
推荐
要使用Flex兼容的词法分析器将模式与中文字符和其他Unicode代码点匹配,可以使用与Flex向后兼容的RE/flex lexical analyzer for C++。RE/flex支持Unicode,并与野牛一起构建词法分析器和解析器。
您可以在RE/flex规范中编写Unicode模式(和UTF-8正则表达式),例如:
使用全局
%option unicode
来启用Unicode。您还可以使用局部修饰符(?u:)
将Unicode限制为单个模式(因此其他内容仍然是ASCII/8位,如Flex中所示):选项
flex
启用Flex兼容性,因此您可以使用yytext
、yyleng
、ECHO
等。如果没有flex
选项,RE/flex将接受Lexer方法调用:text()
(对于std::string
和std::wstring
,或者str()
和wstr()
)、size()
(对于宽字符长度,或者wsize()
)和echo()
。RE/flex方法调用是更干净的IMHO,并且包括宽字符操作。背景
在普通的老Flex中,我最终定义了丑陋的UTF-8模式来捕获ASCII字母和UTF-8编码的字母,用于需要支持Unicode标识符
id
的编译器项目: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+ D 7 FF和U+E000到U+10 FFFF。范围U+D800到U+DFFF是为UTF-16代理对保留的,并且是无效代码点。使用工具将Unicode范围转换为UTF-8时,请确保排除无效的代码点。
1.模式应该拒绝过长的和其他无效的字节序列。无效的UTF-8不应该被默认接受。
1.要在lexer中捕获词法输入错误,需要一个特殊的
.
(dot)匹配有效和无效的Unicode,包括UTF-8溢出和无效的字节序列,以便产生输入被拒绝的错误消息。如果您使用dot作为“catch-all-else”来产生错误消息,但您的dot不匹配无效的Unicode,那么你的lexer将挂起(“scanner is camming”)或者你的lexer将在Flex的“default rule”输出中显示垃圾字符。1.您的扫描仪应识别输入中的UTF BOM(Unicode字节顺序标记),以切换到UTF-8、UTF-16(LE或BE)或UTF-32(LE或BE)。
1.正如您所指出的,像
[unicode characters]
这样的模式在Flex中根本不起作用,因为方括号列表中的UTF-8字符是多字节字符,每个单字节字符都可以匹配,但不能匹配UTF-8字符。另请参阅RE/flex用户指南中的无效UTF编码。
e0uiprwp5#
对于大多数编程语言,匹配99.9%以上中文字符的正则表达式为:
\u4E00-\u9FFF
如果你的语言在其他答案中不支持像
{Han}
/{script=Han}
/{IsCJKUnifiedIdeographs}
这样的符号,这很有用。注:这对应于CJK Unified Ideographs,并包括其他语言,如韩语,日语和越南语。
blpfk2vs6#
在Java 7和更高版本中,格式应该是:“\p{IsHan}”
gstyhher7#
刚刚解决了一个类似的问题
当你有太多的东西要匹配时,最好使用
negated-set
并声明你不想匹配的东西:所有但不是数字:
^[^0-9]*$
第二个
^
将实现否定u4dcyp6a8#
就像这样