平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“正则表达式匹配Unicode和其他字符的做法”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。
待匹配文本:
"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((链接已移除))中,随后输入这个正则表达式:
x{00e9}


实际处理时,u之后紧跟十六进制值00e9(这里不区分大小写,即00E9也能够)。00e9对应十进制值233,在ASCII范围(0~127)之外。
结合项目来看,注意在Regexpal中字母é(小写e加上一个重音符)被标亮了(参见图6-1)。这是因为在Unicode中é就是代码点U+00E9,所以就被u00e9匹配。
结合项目来看,Regexpal采用的是JavaScript的正则表达式实现。JavaScript也允许你采用下面的语法:
xe9

落到代码里,让我们在另一个正则表达式处理引擎中试一下。请在浏览器中打开(链接已移除)。Regex Hero是用.NET编写的且语法稍有不同。将文件basho.txt中的内容放入标签为Target String的文本区域中。其内容包含日本诗人松尾芭蕉(Matsuo Basho,他恰巧是在伏尔泰出生的前一周去世的)的俳句。
以下是该诗的日文版:
古池
蛙飛び込む
水の音
—芭蕉 (1644-1694)
下面是该诗的英译版:
At the ancient pond
a frog plunges into
the sound of water.
—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功能相似(见(链接已移除))。系统一般不会附带这个程序,用户需自己下载同时安装。
落到代码里,我们要用ack来处理席勒1785年的作品“An die Freude”的片段(或许你不认识,这是德语):
An die Freude.
Freude, schöner Götterfunken,
Tochter aus Elisium,
Wir betreten feuertrunken
Himmlische, dein Heiligthum.
Deine Zauber binden wieder,
was der Mode Schwerd getheilt;
Bettler werden Fü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中((链接已移除))。)
在命令行中采用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
实际处理时,在另外一个基于浏览器的正则表达式测试程序(链接已移除)。下图展示的是采用小写字母属性(p{Ll})标亮席勒诗中小写字母的结果。

在这个场景下,下表列出了在p{property}或P{property}中采用的字符属性名(参见(链接已移除)))。

4、匹配控制字符
理解这一步时,如何匹配控制字符呢?虽然你很少会在文本中查找控制字符,但知道如何做也不是件坏事。在示例库中,你会找到ascii.txt文件(共128行),包含了所有的ASCII字符,一个字符占一行(所以有128行)。当你在该文件中查找时,若找到匹配项就得到一行。这个文件用来试试手挺不错的。
在正则表达式里,能够像这样来指定一个控制字符:
cx
其中x就是你想匹配的控制字符。
比如,要在一个文件中查找空字符,能够采用以下Perl命令:
perl -n -e 'print if /c@/' ascii.txt
若系统中已经安装了Perl且运行正常,就能够得到以下结果:
0. Null
原因是该行有一个空字符,只是结果中看不到这个字符。
还能够用 来查找空字符。试一下这个命令:
perl -n -e 'print if / /' 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将其看做一个退格符。
下表列出了匹配字符的方法。

到此这篇关于正则表达式匹配Unicode和其他字符的方法的文章就介绍到这了,更多相关正则表达式匹配Unicode内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!
- 正则表达式之 Unicode 匹配特殊字符
- PHP中正则表达式对UNICODE字符码的匹配方法
- 正则表达式模式匹配的轻松方式
- 正则表达式匹配不包含指定字符串的文本实例演示
- 正则表达式中单个字符的匹配方法教程
- 正则表达式特别需留意的点:“空“字符的匹配方法
- 用正则表达式匹配字符串中汉字及中文标点符号
- 正则表达式之字符串模式匹配实例详解