正则表达式小甲鱼分析_第1页
正则表达式小甲鱼分析_第2页
正则表达式小甲鱼分析_第3页
正则表达式小甲鱼分析_第4页
正则表达式小甲鱼分析_第5页
已阅读5页,还剩6页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、正则表达式介绍(一)正则表达式( Regular expressi ons 也称为 REs,或 regexes 或 regex patter ns )本质上 是一个微小的且高度专业化的编程语言。它被嵌入到Python中,并通过re模块提供给程序猿使用。使用正则表达式,你需要指定一些规则来描述那些你希望匹配的字符串集合。这些字符串集合可能包含英语句子、e-mail地址、TeX命令,或任何你想要的东东。正则表达式模式被编译成一系列的字节码,然后由一个C语言写的匹配引擎所执行。对于高级的使用,你可能需要更关注匹配引擎是如何执行给定的RE,并通过一定的方式来编写RE,以便产生一个可以运行得更快的字节码

2、。本文暂不讲解优化的细节,因为这需要你对 匹配引擎的内部机制有一个很好的理解。但本文的例子均是符合标准的正则表达式语法。小甲鱼注释:Python的正则表达式引擎是用C语言写的,所以效率是极高的。另,所谓 的正则表达式,这里说的RE,就是上文我们提到的“一些规则”。正则表达式语言相对较小,并且受到限制,所以不是所有可能的字符串处理任务都可以使用正则表达式来完成。还有一些特殊的任务,可以使用正则表达式来完成,但是表达式会因此而变得非常复杂。在这种情况下,你可能通过自己编写Pyth on 代码来处理会更好些;尽管Pyth on代码比一个精巧的正则表达式执行起来会慢一些,但可能会更容易理解。小甲鱼注释

3、:这可能是大家常说的丑话说在前”吧,大家别管他,正则表达式非常优秀, 她可以处理你98.3%的文本任务,一定要好好学哦简单的模式我们将从最简单的正则表达式学习开始。由于正则表达式常用于操作字符串的,因此我们从最常见的任务下手:字符匹配。字符匹配大多数字母和字符会匹配它们自身。举个例子,正则表达式FishC将完全匹配字符串FishC。(你可以启用不区分大小写模式,这将使得FishC可以匹配FISHC或fishc,我们会在后边讨论这个话题。)当然这个规则也有例外。有少数特殊的字符我们称之为元字符(metacharacter ),它们并不能匹配自身,它们定义了字符类、子组匹配和模式重复次数等。本文用

4、很大的篇幅专门讨论了各种元字符及其作用。下边是元字符的完整列表(我们将在后边逐一讲解):.A $ * + ? I ()小甲鱼注释:如果没有这些元字符,正则表达式就变得跟字符串的find()方法一样平庸了我们先来看下方括号,它们指定一个字符类用于存放你需要匹配的字符集合。可以单独列出需要匹配的字符,也可以通过两个字符和一个横杆-指定匹配的范围。例如abc会匹配字符a,b或c ; a-c可以实现相同的功能。后者使用范围来表示与前者相同的字符 集合。如果你想只匹配小写字母,你的RE可以写成a-z。需要注意的一点是:元字符在方括号中不会触发“特殊功能”,在字符类中,它们只匹配自身。例如akm$会匹配任

5、何字符a,k,m或$,$是一个元字符,但在方括号 中它不表示特殊含义,它只匹配$字符本身。你还可以匹配方括号中未列出的所有其他字符。做法是在类的开头添加一个脱字符号a ,例如F5会匹配除了 5之外的任何字符。或许最重要的元字符当属反斜杠了。跟Python的字符串规则一样,如果在反斜杠后边紧跟着一个元字符,那么元字符的“特殊功能”也不会被触发。例如你需要匹配符号你可以在它们前面加上一个反斜杠,以消除它们的特殊功能:,。反斜杠后边跟一些字符还可以表示特殊的意义,例如表示十进制数字,表示所有的字母或者表示非空白的字符集合。小甲鱼解释:反斜杠真牛逼,反斜杠后边跟元字符去除特殊功能,反斜杠后边跟普通字符

6、 实现特殊功能。让我们来举个例子: w匹配任何字符。如果正则表达式以字节的形式表示,这相当于字符 类a-zA-Z0-9_;如果正则表达式是一个字符串,w会匹配所有Unicode数据库(uni codedata模块提供)中标记为字母的字符。你可以在编译正则表达式的时候,通过提供re.ASCII表示进一步限制 w的定义。小甲鱼解释:re.ASCII标志使得w只能匹配ASCII字符,不要忘了,Python3是Uni code 的。下边列举一些反斜杠加字符构成的特殊含义:特殊字符含义d匹配任何十进制数字;相当于类0-9D与d相反,匹配任何非十进制数字的字符;相当于类人0-9s匹配任何空白字符(包含空格

7、、换行符、制表符等);相当于类tnfvS与s相反,匹配任何非空白字符;相当于类F tnrfvw匹配任何字符,见上方解释W于w相反b匹配单词的开始或结束B与b相反它们可以包含在一个字符类中,并且一样拥有特殊含义。例如S,.是一个字符类,它将匹配任何空白字符(/S的特殊含义),,或.。最后我们要讲的一个元字符是,它匹配除了换行符以外的任何字符。如果设置了re.DOTALL标志,.将匹配包括换行符在内的任何字符。重复的事情使用正则表达式能够轻松的匹配不同的字符集合,但Pyth on字符串现有的方法却无法实现。然而,如果你认为这是正则表达式的唯一优势,那你就too young too native 了

8、。正则表达式有另一个强大的功能,就是你可以指定RE部分被重复的次数。我们来看看*这个元字符,当然它不是匹配*字符本身(我们说过元字符都是有特殊能力的),它用于指定前一个字符匹配零次或者多次。例如ca*t将匹配ct ( 0个字符a), cat ( 1个字符a), caaat ( 3个字符a),等等。 需要注意的是,由于受到C语言的int类型大小的内部限制,正则表达式引擎会限制字符a的重复个数不超过 20亿个;不过,通常我们工作中也用不到那么大的数据。正则表达式默认的重复规则是贪婪的,当你重复匹配一个RE时,匹配引擎会尝试尽可能多的去匹配。直到RE不匹配或者到了结尾,匹配引擎就会回退一个字符,然后

9、再继续尝试匹配。我们通过例子一步步的给大家讲解什么叫贪婪”:先考虑一下表达式abcd*b ,首先需要匹配字符a,然后是零个到多个 bcd,最后以b结尾。那现在想象一下,这个RE匹配字符串abcbd 会怎样?止 步骤匹配说明1a匹配RE的第一个字符a2abcbd引擎在符合规则的情况下尽可能地匹配bed*,直到该字符串的结尾3失败引擎尝试匹配 RE最后一个字符b,但当前位置已经是字符串的结尾,所以失败告终4abcb回退,所以bed*匹配少一个字符5失败再一次尝试匹配RE最后一个字符b,但字符串最后一个字符是d,所以失败告终6abc再次回退,所以bcd*这次只匹配be7abcb再一次尝试匹配字符b,

10、这一次字符串当前位置指向的字符正好是b,匹配成功最终,RE匹配的结果是abcb。小甲鱼解释:正则表达式默认的匹配规则是贪婪的,后边有教你如何使用非贪婪的方法匹另一个实现重复的元字符是 +,用于指定前一个字符匹配一次或者多次。要特别注意*和+的区别:*匹配的是零次或者多次,所以被重复的内容可能压根儿不会 出现;+至少需要出现一次。例如 ca+t会匹配cat和caaat,但不会匹配 ct。还有两个表示重复的元字符,其中一个是问号?,用于指定前一个字符匹配零次或者一次。你可以这么想,它的作用就是把某种东西标志位可选的。例如小?甲鱼 可以匹配 小甲鱼,也可以匹配甲鱼。最灵活的应该是元字符m, n (m

11、和n都是十进制整数),上边讲到的几个元字符都可以使用它来表达,它的含义是前一个字符必须匹配m次到n次之间。例如a/1,3b会匹配a/b ,a/b和a/b。但不会匹配 ab (没有斜杠);也不会匹配a/b (斜杠超过三个)。你可以省略m或者n,这样的话,引擎会假定一个合理的值代替。省略m,将被解释为下限0 ;省略n则会被解释为无穷大(事实上是上边我们提到的20亿)。小甲鱼解释:如果是, n相当于0, n;如果是m, 相当于m, +无穷;如果是n, 则是重复前一个字符n次。聪明的鱼油应该已经发现了,其实 *、+和?都可以使用m, n来代替。0,跟*是一样 的;1, 跟+是一样的;0, 1跟?是一样

12、的。不过还是鼓励大家记住并使用*、+和?,因为这些字符更短并且更容易阅读。小甲鱼解释:还有一个原因是匹配引擎对* + ?做了优化,效率要更高些。使用正则表达式(二)现在我们开始来写一些简单的正则表达式吧。Python通过re模块为正则表达式引擎提供一个接口,同时允许你将正则表达式编译成模式对象,并用它们来进行匹配。小甲鱼解释:re模块是使用C语言编写,所以效率比你用普通的字符串方法要高得多;将 正则表达式进行编译(compile )也是为了进一步提高效率;后边我们会经常提到模式”,指的就是正则表达式被编译成的模式对象。编译正则表达式 正则表达式被编译为模式对象,该对象拥有各种方法供你操作字符串

13、,如查找模式匹配或 者执行字符串替换。 import re p = pile(ab*) p复制代码pile()也可以接受flags参数,用于开启各种特殊功能和语法变化,我们会在后边一 一介绍。现在我们先来看个简单的例子: p = pile(ab*, re.IGNORECASE)复制代码正则表达式作为一个字符串参数传给pile()。由于正则表达式并不是Python的核心部分,因此没有为它提供特殊的语法支持,所以正则表达式只能以字符串的形式表示。(有些应用根本就不需要使用到正则表达式,所以Python社区的小伙伴们认为没有必要将其纳入Python的核心。)相反,re模块仅仅是作为 C的扩展模块包含

14、在 Python中, 就像socket模块和zlib模块。使用字符串来表示正则表达式保持了Python简洁的一贯风格,但也因此有一些负面影响,下边我们就来谈一谈。麻烦的反斜杠上一篇中我们已经提到了,正则表达式使用字符来使得一些普通的字符拥有特殊的能力(例如d表示匹配任何十进制数字),或者剥夺一些特殊字符的能力(例如表示匹配左方括号)。这会跟Python字符串中实现相同功能的字符发生冲突。小甲鱼解释:挺拗口,接着看例子你就懂了现在的情况是,你需要在LaTeX文件中使用正则表达式匹配字符串section。因为反斜杠作为需要匹配的特殊字符,所以你需要再它前边加多一个反斜杠来剥夺它的特殊功能。但不要忘

15、了,Python在字符串中同样使用反斜杠来表示特殊意义。因此,如果我们想将section完整地传给pile(),我们需要再次添加两个反斜杠 匹配字符匹配阶段section需要匹配的字符串section正则表达式使用表示匹配字符WWsection不巧,Python字符串也使用表示字符简而言之,为了匹配反斜杠这个字符,我们需要在字符串中使用四个反斜杠才行。所以, 在正则表达式中频繁地使用反斜杠,会造成反斜杠风暴,进而导致你的字符串极其难懂。r,大家解决方法是使用 Python的原始字符串来表示正则表达式(就是在字符串前边加上还记得吧.)正则字符串原始字符串ab*rab*WWsectio nrsec

16、tio n w+s+1rw+s+1小甲鱼解释:强烈建议使用原始字符串来表达正则表达式。实现匹配当你将正则表达式编译之后,你就得到一个模式对象。那你拿他可以用来做什么呢?模式 对象拥有很多方法和属性,我们下边列举最重要的几个来讲:方法功能match()判断一个正则表达式是否从开始处匹配一个字符串search()遍历字符串,找到正则表达式匹配的第一个位置findall()遍历字符串,找到正则表达式匹配的所有位置,并以列表的形式返回finditer()遍历字符串,找到正则表达式匹配的所有位置,并以迭代器的形式返回如果没有找到任何匹配的话,match()和search。会返回None ;如果匹配成功,

17、则会返回一个匹配对象(match object ),包含所有匹配的信息:例如从哪儿开始,到哪儿结束, 匹配的子字符串等等。接下来我们一步步讲解: import re p = pile(a_z+) ppile(a-z+)复制代码现在,你可以尝试使用正则表达式a-z+去匹配各种字符串。例如: p.match() prin t(p.match()None复制代码match()返回 None。m中,以便日后使用。因为+表示匹配一次或者多次,所以空字符串不能被匹配。因此,我们再尝试一个可以匹配的字符串: m = p.match(fishc) m 复制代码在这个例子中,match()返回一个匹配对象,我们

18、将其存放在变量接下来让我们来看看匹配对象里边有哪些信息吧。匹配对象包含了很多方法和属性,以下 几个是最重要的:方法功能group()返回匹配的字符串 start()返回匹配的开始位置end()返回匹配的结束位置span()返回一个元组表示匹配位置(开始,结束)大家看: m.group() fishc m.start()0 m.en d()5 m.spa n()(0, 5)复制代码由于match()只检查正则表达式是否在字符串的起始位置匹配,所以start()总是返回0。然而,search()方法可就不一样咯: prin t(p.match(A_Afishc)None m = p.search(人_人 fishc) prin t(m) m.group()fishc m.spa n()(3, 8)复制代码在实际应用中,最常用的方式是将匹配对象存放在一个局部变量中,并检查其返回值是否为 None 。形式通常如下:p = pile( .)m = p.match( stri ng goes here) if m:prin t(Match foun d: , m.group() else:prin t(No match)f

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论