匹配Unicode和其他字符
- 1、匹配Unicode字符
- 2、用八进制数匹配字符
- 3、匹配Unicode字符属性
- 4、匹配控制字符
待匹配文本:
"Qu'est-ce que la tolérance? c'est l'apanage del'humanité. Nous sommes tous pétris defaiblesses et d'erreurs; pardonnons-nous réciproquement nos sottises, c'est la première loi de la nature."-Voltaire(1694-1778)1、匹配Unicode字符
有很多方式可以指定Unicode字符(也称为代码点)。为了讲解方便,本书将Unicode字符看做ASCII字符范围以外的字符,但严格说来这并不准确。
先将伏尔泰的名言输入到Regexpal(http://www.regexpal.com)中,然后输入这个正则表达式:
\x{00e9}
\u之后紧跟十六进制值00e9(这里不区分大小写,即00E9也可以)。00e9对应十进制值233,在ASCII范围(0~127)之外。
注意在Regexpal中字母é(小写e加上一个重音符)被标亮了(参见图6-1)。这是因为在Unicode中é就是代码点U+00E9,所以就被\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-255(0-FF)范围内的值,使用u匹配256-65535(100-FFFF)范围内的四位十六进制数,还可以用U来匹配65536-2147483647(10000-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'\pL'schiller.txt该命令会将字母都高亮显示。对于小写字母,则要在括号中使用Ll:
ack'\p{Ll}'schiller.txt括号是必需的。对于大写字母,则是Lu:
ack'\p{Lu}'schiller.txt要指定不符合某个属性的字符,则使用大写P:
ack'\PL'schiller.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-e'print if /\c@/'ascii.txt如果系统中已经安装了Perl且运行正常,就可以得到以下结果:
0. Null原因是该行有一个空字符,只是结果中看不到这个字符。
还可以用\0来查找空字符。试一下这个命令:
perl-n-e'print if /\0/'ascii.txt再用以下命令来查找报警字符(BEL):
perl-n-e'print if /\cG/'ascii.txt这将返回:
7. Bell或者还可以使用简写式:
perl-n-e'print if /\a/'ascii.txt要查找转义字符,则使用:
perl-n-e'print if /\c[/'ascii.txt它的结果是:
27. Escape或者使用简写式:
perl-n-e'print if /\e/'ascii.txt如何匹配退格符呢?试一下这个:
perl-n-e'print if /\cH/'ascii.txt它显示:
8. Backspace也可以使用分类表达式来查找退格符:
perl-n-e'print if /[\b]/'ascii.txt如果没有括号,\b会被认为是什么呢?是第2章中所学到的单词边界。括号改变了正则表达式处理器对\b的理解方式。在本例中,Perl将其看做一个退格符。
下表列出了匹配字符的方法。