正则表达式——匹配Unicode和其他字符

📅 2026/8/6 18:44:38
正则表达式——匹配Unicode和其他字符
匹配Unicode和其他字符1、匹配Unicode字符2、用八进制数匹配字符3、匹配Unicode字符属性4、匹配控制字符待匹配文本Quest-ce que la tolérance? cest lapanage delhumanité. Nous sommes tous pétris defaiblesses et derreurs; pardonnons-nous réciproquement nos sottises, cest la première loi de la nature.-Voltaire(1694-1778)1、匹配Unicode字符有很多方式可以指定Unicode字符也称为代码点​。为了讲解方便本书将Unicode字符看做ASCII字符范围以外的字符但严格说来这并不准确。先将伏尔泰的名言输入到Regexpalhttp://www.regexpal.com中然后输入这个正则表达式\x{00e9}\u之后紧跟十六进制值00e9这里不区分大小写即00E9也可以​。00e9对应十进制值233在ASCII范围0127之外。注意在Regexpal中字母é小写e加上一个重音符被标亮了参见图6-1​。这是因为在Unicode中é就是代码点U00E9所以就被\u00e9匹配。Regexpal使用的是JavaScript的正则表达式实现。JavaScript也允许你使用下面的语法\xe9让我们在另一个正则表达式处理引擎中试一下。请在浏览器中打开http://regexhero.net/tester/。Regex Hero是用NET编写的且语法稍有不同。将文件basho.txt中的内容放入标签为Target String的文本区域中。其内容包含日本诗人松尾芭蕉Matsuo Basho他恰巧是在伏尔泰出生的前一周去世的的俳句。以下是该诗的日文版古池 蛙飛び込む 水の音—芭蕉(1644-1694)接下来是该诗的英译版At the ancient pond a frog plunges into the soundofwater.—Basho(1644-1694)请在标签为Regular Expression的文本区中键入以下内容来匹配日文文本的部分内容\x{6c60}这是单词pond池塘所对应的日文字符的代码点该字会在下方被标亮​。另外你可以试一下匹配长破折号—​\x{2014}使用vim如果你的系统里有vim可以用它打开basho.txt文件如下所示vim basho.txt现在以斜线/为起始输入下面一行来查找/\%u6c60然后键入回车Enter或Return​。如图所示光标移到了匹配部分的起始处。下表列出了可以设置的选项。在%之后你可以使用x或X来匹配0-2550-FF范围内的值使用u匹配256-65535100-FFFF范围内的四位十六进制数还可以用U来匹配65536-214748364710000-7FFFFFFF范围内的八位十六进制数。这样就能涵盖很多编码其数量远远超过Unicode现有的字符编码数量。2、用八进制数匹配字符还可以使用八进制数来匹配字符八进制数以8为基数使用数字0到7计数。在正则表达式处理器中就是要在反斜线\后加三位数字。比如以下八进制数\351等同于\u00e9请在Regexpal中用伏尔泰的文本实验一下。\351匹配é键入的内容少了一点儿。3、匹配Unicode字符属性在某些实现比如像Perl中还可以匹配Unicode的字符属性。这些属性包括字符是否是字母、数字或标点符号。现在介绍一下ack这是一个用Perl语言编写的命令行工具它跟grep功能相似见http://betterthangrep.com​。系统一般不会附带这个程序用户需要自己下载并安装。我们要用ack来处理席勒1785年的作品“An die Freude”的片段或许你不认识这是德语​An die Freude.Freude,schönerGötterfunken,Tochter aus Elisium,Wir betreten feuertrunken Himmlische,dein Heiligthum.Deine Zauber binden wieder,was der Mode Schwerd getheilt;Bettler werdenFürstenbrüder,wo dein sanfter Flügel weilt.Seid umschlungen,Millionen!Diesen Kuß der ganzen Welt!Brüder,überm Sternenzelt muß ein lieber Vater wohnen.该片段中有几个有趣的字符它们不在ASCII的范围内。我们要通过属性来看看这首诗的文本内容。​如果你想知道这段文字的意思可以将其输入到Google Translate中http://translate.google.com​。​在命令行中使用ack时你可以指定查看那些属性为字母L的字符ack\pLschiller.txt该命令会将字母都高亮显示。对于小写字母则要在括号中使用Llack\p{Ll}schiller.txt括号是必需的。对于大写字母则是Luack\p{Lu}schiller.txt要指定不符合某个属性的字符则使用大写Pack\PLschiller.txt这个命令会将非字母字符标亮。下面的正则表达式用于查找非小写字母ack\P{Ll}schiller.txt而这个正则表达式则高亮显示非大写字母ack\P{Lu}schiller.txt在另外一个基于浏览器的正则表达式测试程序http://regex.larsolavtorvik.com中也可以这样做。下图展示的是使用小写字母属性\p{Ll}标亮席勒诗中小写字母的结果。下表列出了在\p{property}或\P{property}中使用的字符属性名参见http://www.pcre.org/pcre.txt中的pcresyntax(3)​。4、匹配控制字符如何匹配控制字符呢虽然你很少会在文本中查找控制字符但知道如何做也不是件坏事。在示例代码库中你会找到ascii.txt文件共128行​包含了所有的ASCII字符一个字符占一行所以有128行​。当你在该文件中查找时若找到匹配项就返回一行。这个文件用来试试手挺不错的。在正则表达式中可以像这样来指定一个控制字符\cx其中x就是你想匹配的控制字符。例如要在一个文件中查找空字符可以使用以下Perl命令perl-n-eprint if /\c/ascii.txt如果系统中已经安装了Perl且运行正常就可以得到以下结果0. Null原因是该行有一个空字符只是结果中看不到这个字符。还可以用\0来查找空字符。试一下这个命令perl-n-eprint if /\0/ascii.txt再用以下命令来查找报警字符BEL​perl-n-eprint if /\cG/ascii.txt这将返回7. Bell或者还可以使用简写式perl-n-eprint if /\a/ascii.txt要查找转义字符则使用perl-n-eprint if /\c[/ascii.txt它的结果是27. Escape或者使用简写式perl-n-eprint if /\e/ascii.txt如何匹配退格符呢试一下这个perl-n-eprint if /\cH/ascii.txt它显示8. Backspace也可以使用分类表达式来查找退格符perl-n-eprint if /[\b]/ascii.txt如果没有括号\b会被认为是什么呢是第2章中所学到的单词边界。括号改变了正则表达式处理器对\b的理解方式。在本例中Perl将其看做一个退格符。下表列出了匹配字符的方法。