IT俱乐部 正则表达式 正则表达式匹配Unicode和其他字符的方法

正则表达式匹配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(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 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功能相似(见http://betterthangrep.com)​。系统一般不会附带这个程序,用户需要自己下载并安装。

我们要用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中(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

原因是该行有一个空字符,只是结果中看不到这个字符。

还可以用来查找空字符。试一下这个命令:

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内容请搜索IT俱乐部以前的文章或继续浏览下面的相关文章希望大家以后多多支持IT俱乐部!

本文收集自网络,不代表IT俱乐部立场,转载请注明出处。https://www.2it.club/navsub/regex/18727.html
上一篇
下一篇
联系我们

联系我们

在线咨询: QQ交谈

邮箱: 1120393934@qq.com

工作时间:周一至周五,9:00-17:30,节假日休息

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部