`
anson_xu
  • 浏览: 513122 次
  • 性别: Icon_minigender_1
  • 来自: 惠州
社区版块
存档分类

第七章正则表达式

阅读更多
第七章正则表达式
Perl 有许多区别于其它语言的特性。在所有这些特性中,最重要的一条是对正则表达式的支持。它允许你方便,快捷的处
理字符串相关的问题。
但是获得这种能力是需要付出代价的。正则表达式(regular expressions)是一种特殊语言写成的程序,内嵌于Perl 之中(是的,
你要学习一门新的程序语言◆。庆幸的是,它非常简单。)。从本章开始,我们将进入正则表达式的世界,现在你可以暂时
忘掉Perl。下一章中,我们将介绍如何在Perl 中使用正则表达式。
◆ 一些人可能争论说正则表达式不是完备的程序语言。我们不准备在这里争论这个问题。
正则表达式不仅仅是Perl 的一部分;在sed, awk, procmail, grep, 以及许多程序员文本编辑器(programmer’s text editor)如vi,
emacs,还有一些更深奥的程序中都有它的踪影。注意观察,你可以发现许多工具都支持正则表达式,如Web 上的搜索引
擎(通常由Perl 书写),email 客户端,等等。不幸的消息是,不同的正则表达式的实现中,语法会有些微的不同,因此需
要学习其不同的地方,例如需要还是不需要反斜线(\)。
7.1 什么是正则表达式?
正则表达式,在Perl 中通常被称为模式(pattern):某个模板是否匹配某个字符串◆。由于存在无限的字符串,某个给定的模
式将这些字符串分成两类:一类是能匹配的,一类是不能匹配的。这里没有,或者,大概,几乎那样的匹配:要么匹配,
要么不匹配。
◆某些学究可能认为这个定义不够严格。他们可能会说Perl 的模式根本不是真正意义上的正则表达式。如果你想知道更多的关于正则表达
式的信息可以参看Jeffrey Friedl(O’Reily)的书籍《掌握正则表达式》(Mastering Regular Expessions)。
一个模式可以匹配多个字符串:1个,2个,3个,上百个,或者无限个。也可能匹配除了1个,多个,或者无限个字符
串之外的所有字符串◆。我们将正则表达式看作一种由简单语言实现的程序,这种语言只有一个任务:查找某个字符串,
返回“匹配上(it matches)”或者“不匹配(it doesnot match)”◆。这就是它完成的所有工作。
◆将学习到,你可以让某个模式永远匹配或者永不匹配。在极少情况下,这也是有用的,但通常是错误。
◆程序也返回一些信息给Perl。其中的一种信息是“正则表达式内存(regular expressions memories)”,这将在后面会学习到。
你可能在使用Unix 的grep 命令时,见过正则表达式,它会输出匹配上模式的行。例如,如果想查看某个给定文件中是否
某行提到过flint,同时同一行后面提到stone,那你可以如下的使用grep 命令:
$grep‘flint.*stone’chapter*.txt
chapter3.txt:a piece of flint, a stone which may be used to start a fire by striking
Perl 语言入门(第四版)
blei@163.com 93 / 201 9/21/2006
chapter3.txt:found obsidian, flint, granite, and small stones of basaltic rock, which
chapter9.txt:a flintlock rifle in poor condition. The sandstone mantle held several
不要将正则表达式和shell 中的文件名匹配模式,globs 混淆了。通常glob 是指,在Unix shell 下输入*.pm 将匹配所有结尾
为.pm 的文件名。上一个例子使用的glob 为chapter*.txt。(你可能已经注意到我们将模式括起来了,来防止shell 将其作为
glob 来处理)虽然glob 和正则表达式有许多相同的符号,但其作用并不相同◆。第十二章中将介绍globs。
◆globs 有时也被称作模式。但严重的问题是,某些面向初级用户的书籍(可能是菜鸟写得)将globs 叫做“正则表达式”,这绝对是错误
的。
7.2 使用简单的模式
要匹配某个模式(正则表达式)和$_的关系,可以将模式放在正斜线(//)之间,如下:
$_ =“yabba dabba doo”;
if(/abba/){
print “It matched!\n”;
}
表达式/abba/将在$_寻找这四个字母。如果找到,则返回true,在本例中,它出现了不止一次,但结果没什么不同。总之,
如果找到了,则匹配上;如果没找到,则没匹配上。
由于模式匹配通常返回true 或false,因此经常用在if 或while 的条件表达式部分。
所有在双引号中的转义字符在模式中均有效,因此你可以使用/coke\tsprite/来匹配11 个字符的字符串coke, tab(制表符),
sprite。
7.2.1 元字符
如果模式只能匹配字面上的字符串,则其用处不会太大。这也是引入特殊字符的原因,它们被叫做元字符(metacharacters),
在正则表达式中具有特殊的含义。
例如,点(.)是通配符,它可以匹配任何单个的字符,但不包括换行符(“\n”)。因此,模式/bet.y/将匹配betty。同时也匹配betsy,
bet=y, bet.y,或者说任意字符串后接bet,然后是任意的单个字符(不包括换行符),后接y。它不会匹配bety,betsey,因为
t 和y 之间不是一个字符。点(.)只匹配一个字符。
如果想匹配句号(英语中句号就是一个点:译者注),可以使用点(.)。但由于点(.)可以匹配任意的单个字符(除换行符外),
则其结果比你希望的要多。如果只希望点(.)匹配句号,可以使用反斜线。这条规则对Perl 正则表达式中所有元字符均有效:
元字符前使用反斜线将使它变成普通的字符。如,模式/3\.14159/中的点(.)即不是通配符。
反斜线是第二个元字符。如果需要真正的反斜线,需要重复使用两个反斜线,这和Perl 中其它情况下是一样的。
Perl 语言入门(第四版)
blei@163.com 94 / 201 9/21/2006
7.2.2 简单的量词
通常,需要模式中某些串是可以重复的。星号(*)表示匹配前一项0次或者多次。因此,/fred\t*barney/将匹配上fred 和barney
之间有任意个制表位(tab)的字符串。它可以匹配“fred\tbarney”,其间有一个tab;匹配“fred\t\tbarney”,其间有两个制表位;
“fred\t\t\tbarney”其间有三个制表位;“fredbarney”,其间什么也没有。这是由于星号(*)是指“0 个或者多个”,因此其间可以
是任意个制表符,但不能是其它的字符。可以这样看待星号(*):“前面的东西,重复任意次数,包括0 次”(因为*号在数
学上是乘法运算符)。
如果希望包括不同的字符,怎么办呢?点(.)可以匹配任何单字符◆,因此.*将匹配任意字符任意多数。这就是说模式
/fred.*barney/将匹配fred,和barney 之间有任意多个任意字符(不含换行符)的字符串。任意行如果前面有fred,后面有barney,
其间为任意字符(字符串)都将匹配上。我们将.*叫做“任意字符串匹配模式”,因为任意的字符串均能被匹配上(不包括
换行符)。
◆除了换行符。以后我们将不再提醒你,因为你已经知道了。许多时候你不用担心这个问题,因为通常你的字符串中并不含有换行符。但
不应该把这个细节忘掉,因为说不定某人就在你的字符串中加入了换行符,因此应当记住点(.)不会匹配换行符。
星号的正是叫法是数量词(quantifier),意指其可以指代多个前面的项。它不是唯一的数量词,加(+)也是。加(+)的意思是可
以匹配前面一项的一个或多个:/fred +barney/意思是fred 和barney 之间由空格分开,且只能是空格。(空格不是元字符)。
它不会匹配fredbarney,因为加(+)意指一个或多个,因此至少是一个。可以这样看待加(+):“最后一项,(可选的)至少还
有一项。”
还有第三个数量词,其限制性更强。它是问号(?),其含义是前面一个项出现一次,或者不出现。也就是说,前面这个项出
现1 次或者0 次,此外不会有其它情况。因此,/barm-?bamm/只匹配:bamm-bamm 或bammbamm。这很容易记住:“前面
的这个项,出现?或者不出现?”
这三个数量词必须紧跟在某些项的后面,因为它是指前面项重复的次数。
7.2.3 模式中的分组
括号也是元字符。在数学中,括号(())用来表示分组。例如,模式/fred+/能匹配上如fredddddddd,这样的字符串,但这种字
符串在实际中没有什么用途。模式/(fred)+/能匹配上像fredfredfred 这样的字符串,这更可能是你所希望的。那么模式/(fred)*/
呢?它将匹配上像hello,world 这样的字符串◆。
◆星号(*)意指匹配上0 次或者多次fred。当为0 时,那什么字符串都能被匹配上。这个模式能匹配上任何字符串,甚至是空串。
7.2.4 选择符
竖线(|),在这种用法中通常被读作“或(or)”,意思是匹配左边的或者右边的。如果竖线左边没有匹配上,则匹配右边。因
此,/fred|barney|betty/将匹配出现过fred,或者barney,或者betty 的字符串。
Perl 语言入门(第四版)
blei@163.com 95 / 201 9/21/2006
现在你可以书写像/fred( |\t)+barney/这样的模式,它将匹配fred,barney 以及中间由空格,制表符(tab),或者二者混合所组
成的字符串。加(+)是指重复1 次或多次;每重复一次,( |\t)则有可能匹配一个空格,或者一个制表符◆。但fred 和barney
之间这些字符中(空格,制表符)的其中之一必须出现一次。
◆如果使用字符类(character class)进行这种匹配将更有效,这在本章后面会介绍。
如果希望fred 和barney 之间的字符是一样的,可以将模式写成/fred( +|\t+)barney/。在本例中,分隔符必须全是空格或者全
是制表符。
模式/fred (and|or) barney/能匹配如下两种字符串:fred and barney, fred or barney◆。也可以将模式写成: /fred and barney|fred
or barney/,但这样书写的字符更多。并且其效率也更低,这依赖于正则表达式引擎中所使用的优化方法。
◆单词and 和or 在正则表达式中不是操作符!它们在正则表达式中就是其本来的含义:单词and,or。
7.3 字符类
字符类,是方括号[]中的一列字符,可以匹配上括号内出现的任意单个字符。它匹配一个字符,但这个字符可以是列中的
任意一个。
例如,字符类[abcwxyz]可以匹配上括号内七个字母中的任意一个。为了方便,我们可以使用连字号(-)来表示某个范围的字
母,因此上例也可以写做[a-cw-z]。上面例子省略的字符不多,但像[a-zA-Z]将非常方便,利用它不需要输入52 个字符◆。
你可以使用和双引号相同的字符简写方法,例如类[\000-\177]可以匹配上任意的七比特的ASCII 字符。◆。当然,字符类
只是模式的一部分,单独的字符类在Perl 中没什么实际的意义。例如,你可能见到如下的代码:
◆注意这52 个字母不包括Å, É, Î, Ø, 和Ü。如果允许处理Unicode,则上述字符的范围将自动的变化,来做正确的工作。
◆这里,使用的是ASCII 而非EBCDIC。
$_ = “The HAL-9000 requires authorization to continue.”;
if(/HAL-[0-9]+/){
print “The string mentions some model of HAL computer.\n”;
}
有时,指出没有被字符类包含的字符更加容易。字符类前使用符号^将取此字符类的补集。也就是说,[^def]]将匹配上这三
个字符中之外的任意单个字符。[^n\-z]将匹配上n, -, z 之外的任何字符。(连接符(-)前面使用反斜线的原因是,它在此字符
类中有特别的含义(表示字符的范围:译者注)。但/HAL-[0-9]+/中第一个连接符(-)前不需要反斜线,因为此时的连接符不
会被理解为有特殊的含义。)
7.3.1 字符类的简写
有一些字符类出现的非常频繁,因此提供了其简写形式。例如,任何数字的类,[0-9],可以被简写为:\d。因此,HAL 这
Perl 语言入门(第四版)
blei@163.com 96 / 201 9/21/2006
个例子可以被写作/HAL-\d+/。
\w 被称作“word’字符:[A-Za-z0-9_]。如果你的“words”由通常的字母,数字,下划线组成,那你将非常喜欢它。通常认
为“word”由字母,连接符(-),撇号(')◆组成,我们希望能改变这种定义◆。因此使用它,请记住我们对“word”的定义,
字母,数字,下划线组成。
◆至少,在英语中是这样。在其它语言中,其words 由不同的符号组成。查看perllocale 的帮助手册了解更多的信息。
◆当查看ASCII 编码的英语文本时,我们遇到单引号和撇号(')是相同字符的问题,因此很难说cat’是cat 和一个撇号( '),还是cat 后接单引
号。这可能是计算机还不能接管世界的一个原因。
当然,\w 不能匹配单词,而只能匹配单个字符。为了匹配整个单词,需要后接加号。模式/fred \w+ barney/将匹配fred,空
格,一个“单词(word)”,然后是空格和barney。因此,如果fred 和barney 之间有一个单词◆,由单个空格分隔开,它将
能匹配上。
◆我们将停止在word 上加引号;现在你已经知道其是由字母-数字-下划线组成的。
你可能已经注意到在前一例中,如果能更加灵活的匹配空白将很方便。\s 对于匹配空白(whitespace)将非常方便。它等价
于[\f\t\n\r ],其含5 个空白字符:格式符(form-feed);制表符(tab),换行符,回车,以及空格符。同其它简写符号一样,
\s 匹配此类中的单个字符,如果使用\s*将匹配任何个数的空白(包括没有),或者\s+匹配一个以上的空白(事实上,很少
见到单独使用\s,而不使用任何的数量词(*, +))。由于这些空白符看起来类似,因此可以使用这种简写形式,将它们统一处
理。
7.3.2 简写形式的补集
某些时候,你可能希望得到这三种简写形式的补集。如果那样的话,你可以使用[^\d], [^\w], 和[^\s],其含义分别是,非数
字的字符,非word(记住我们对word 的定义)的字符,和非空白的字符。也可以使用它们对应的大写形式:\D, \W, \S 来
完成。它们将匹配它们对应的小写形式不能匹配上的字符。
这些简写形式可以在字符类中使用,或者在大的字符类中的中括号里面使用。也就是说你可以使用/[\dA-Fa-f]+/来匹配十六
进制(底为16)的数字,它将ABCDEF(或者其小写形式)作为附加的数字(11 到15)。
另一个类字符[\d\D],它的意思是任何数字,和任何非数字,则意指任何字符。这是匹配所有字符的一种通用方法,甚至包
括换行符,而点(.)匹配除换行符以外的任何字符。而[^\d\D]则完全没用,因为它匹配既非数字也非非数字的字符,那什么
也不是。
分享到:
评论

相关推荐

    《C#.Net 程序设计》课件

    第1章概述 第2章C#数据类型 第3章面向对象的编程基础 第4章面向对象的高级编程 第5章窗体界面设计 第6章目录与文件管理 第7章正则表达式与Internet操作 第8章ADO.NET与SQLServer 第9章二维图形图像处理 第10章基于...

    linux与unix shell编程指南

    第7章正则表达式介绍.PDF 第8章grep 家族.PDF 第9章AWK 介绍.PDF 第10章sed 用法介绍.PDF 第11章合并与分割.PDF 第12章tr 用法.PDF 第13章登录环境.PDF 第14章环境和shell变量.PDF 第15章引号.PDF 第16章shell脚本...

    LINUX与UNIX SHELL编程指南

    第7章正则表达式介绍.PDF 第8章grep 家族.PDF 第9章AWK 介绍.PDF 第10章sed 用法介绍.PDF 第11章合并与分割.PDF 第12章tr 用法.PDF 第13章登录环境.PDF 第14章环境和shell变量.PDF 第15章引号.PDF 第16章shell脚本...

    linuxshell

    第一部分s h e l l 第1章文件安全与权限 第2章使用find和xargs 第3章后台执行命令 第4章文件名置换 第5章shell输入与输出 第6章命令执行顺序 第二部分文本过滤 第7章正则表达式介绍

    LINUX与UNIX_Shell编程指南

    第7章正则表达式介绍 第8章grep 家族 第9章AWK 介绍 第10章sed 用法介绍 第11章合并与分割 第12章tr 用法 第三部分登录环境 第13章登录环境 第14章环境和shell变量 第15章引号 第四部分基础s h e l l编程 第16章...

    linuxshell.rar

    linux shell 命令 第1章文件安全与权限.pdf 第2章使用find和xargs.pdf 第3章后台执行命令.pdf 第4章文件名置换.pdf 第5章shell输入与输出.pdf 第6章命令执行顺序.pdf 第7章正则表达式介绍.pdf

    Perl语言程序设计:第6章 正则表达式和模式匹配.ppt

    第 6 章正则表达式和模式匹配主要讨论了 Perl 语言中正则表达式的使用和模式匹配的技术。正则表达式是一种强大的字符串处理工具,能够帮助开发人员快速地提取、匹配和处理字符串数据。在 Perl 语言中,正则表达式是...

    Python数据分析与挖掘 第5章 正则表达式能用在哪?.rar

    在数据分析和挖掘领域,正则表达式(Regular Expression)...通过阅读"第5章 正则表达式的使用.ipynb"和"第5章正则表达式的使用.pdf",你可以进一步学习和实践正则表达式的各种用法,并将其应用于你的数据分析项目中。

    Shell自学pdf.zip

    第07 章正则表达式介绍.PDF 第08 章grep 家族.PDF 第09 章AWK 介绍.PDF 第10 章sed 用法介绍.PDF 第11 章合并与分割.PDF 第12 章tr 用法.PDF 第13 章登录环境.PDF 第14 章环境和shell 变量.PDF 第15 章引号.PDF 第16...

    形式语言与自动机.rar

    4.3则表达式的等价变换 4.3.1 交换律与结合律 4.3.2 单位元与零元 4.3.3 分配律 4.3.4 与“*”构造有关的定律 4.3.5 发现正则表达式定律的一般方法 4.4 正则表达式的应用 4.4.1UNIX中的正则表达式 4.4.2 词法...

    工程制图CAI教学课件:第02章正投影基础.ppt

    《工程制图CAI教学课件:第02章正投影基础》主要涵盖了工程制图中的核心概念——正投影的基础知识。本章的学习目标旨在帮助学生掌握平行投影的基本性质,理解正投影体系,以及点、直线和平面的投影规律,同时深入...

    ActionScript开发技术大全

    第14章正则表达式与字符串匹配 299 14.1正则表达式概述 299 14.2正则表达式语法 300 14.2.1创建对象 300 14.2.2字符、元字符与元序列 301 14.2.3字符集 306 14.2.4组 307 14.3标记、属性与方法 310 14.3.1正则表达式...

    仿拼多多源码java-NBReader:实现自定义Android书籍渲染引擎的文本阅读器。支持txt,epub书籍富文本渲染、支持自定义hea

    类支持加载书籍(暂不支持加载网络书籍)、自定义分章正则、页面跳转、获取翻页监听、获取页面点击事件等逻辑 演示 翻页效果: 使用 加入 XML <com.newbiechen.nbreader.ui.component.widget.page.PageView android...

    Foundation Actionscript 3.0 Animation

    第7章用户交互:移动物体 7.1按下和放开精灵 7.2拖动精灵 7.2.1使用mouseMove拖动 7.2.2使用startDrag/stopDrag拖动 7.2.3拖动与运动代码结合 7.3抛 7.4小结 第三部分 高级运动 第8章缓动和弹性 8.1比例运动 8.2缓动...

    第4章正弦交流电路

    第4章正第4章正弦交流电路弦交流电路第4章正弦交流电路第4章正弦交流电路第4章正弦交流电路

    嵌入式非接触式公交智能卡项目

    该项目由李永峰和向章正设计,主要涉及智能卡的初始化、读卡器感应以及营业额统计等功能。智能卡系统需具备用户信息存储、余额管理以及与读卡器之间的交互能力。同时,读卡器需能识别和处理卡片信息,如检查余额、...

    基站领跑通信节能.docx

    有着丰富工程经验的章正珊认为,基站节能的重点不应放在基站技术的升级上,而是应该放在网络规划中。“一个好的网络规划,在不影响用户通话质量和减少覆盖的基础上,可以最大限度地降低基站耗电”。

    矿物红外光谱学 闻辂主编

    该书的编写团队由闻辂、章正、梁生雪等人组成,他们根据教学需求和多年的实践经验,对原有的讲义进行了修改和完善。在编写过程中,多位地质学领域的专家进行了审阅和意见提供,帮助提升了书稿的质量。尽管如此,作者...

    部编版第11章+1+反比例函数图象及其性质.docx

    这一部分的内容主要涉及第十一章正比例函数的图像及其性质,以及反比例函数的一些基本概念。 首先,我们要理解正比例函数。正比例函数通常表示为y = kx,其中k是常数,x和y是变量,且k不等于0。这个函数的性质包括...

    画法几何及工程制图:第二章 正投影法基础5.ppt

    画法几何及工程制图:第二章 正投影法基础5.ppt

Global site tag (gtag.js) - Google Analytics