第10章-正则表达式_第1页
第10章-正则表达式_第2页
第10章-正则表达式_第3页
第10章-正则表达式_第4页
第10章-正则表达式_第5页
已阅读5页,还剩36页未读 继续免费阅读

下载本文档

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

文档简介

2024/11/17第10章正则表达式目录2024/11/17210.1正则表达式简介10.2简单模式10.3使用正则表达式10.4更多模式功能10.5修改字符串10.6常见问题2024/11/1710.1正则表达式简介正则表达式(RegularExpressions),通常被简称为REs或regexes,是一些由字符和特殊符号组成的字符串,它们描述了这些字符和字符的某种重复方式,因此能按某种模式匹配一个有相似特征的字符串的集合,也能按某模式匹配一系列有相似特征的字符串。正则表达式提供了一种紧凑的表示法,可用于表示字符串的组合,其之所以功能如此强大,是因为一个单独的正则表达式可以表示无限数量的字符串,只要字符串满足正则表达式的需求即可。正则表达式为高级文本模式匹配,以及文本的搜索与替代等功能提供了基础。目录2024/11/17210.1正则表达式简介10.2简单模式10.3使用正则表达式10.4更多模式功能10.5修改字符串10.6常见问题2024/11/1710.2简单模式10.2.1字符匹配绝大多数字符会与自身匹配。例如,正则表达式test会和字符串“test”完全匹配。这个规则也会有例外,有种字符比较特殊,我们把它们称作元字符(Metacharacters),它们和自身并不匹配,而是会和一些特殊的东西匹配,或者通过某种方式影响到正则表达式的其他部分。元字符的完整列表如下:.^$*+?{}[]\|()2024/11/1710.2简单模式10.2.1字符匹配元字符“[”与“]”用于指定一个字符类,所谓字符类就是你想匹配的一个字符集。字符可以单个列出,也可以用以“-”号分隔的两个给定字符来表示一个字符区间。举个简单的例子,[abc]将匹配“a”“b”或“c”中的任意一个字符,使用区间[a-c]来可以达到与前者一样的目的。只匹配小写字母,那么正则表达式应写成[a-z]元字符在字符类里并不起作用。例如,[abc$]将匹配字符。“a”“b”“c”或“$”中的任意一个,虽然“$”通常用作元字符,但在字符类里,其特性被除去,恢复成普通字符。可以用补集来匹配不在区间范围内的字符。其做法是把“^”作为字符类的首个字符,其他地方的“^”字符只会简单匹配“^”字符本身。例如,[^5]将匹配除了“5”之外的任意字符,而[5^]只会匹配字符“5”和“^”。2024/11/1710.2简单模式10.2.1字符匹配另一个重要的元字符是反斜杠“\”。“\”为Python中的字符串转义字符,可以通过在反斜杠后面加不同的字符以表示不同特殊意义。它也可以用于取消所有的元字符,这样就能够在模式中匹配它们。例如,如果我们需要匹配字符“[”或“\”,可以在它们之前用反斜杠来取消它们的特殊意义:“\[”或“\\”。一些用“\”开始的特殊字符表示预定义的字符集,例如数字集、字母集或其他非空字符集等。2024/11/1710.2简单模式Python的预定义字符集如下:预设特殊字符说

明\d匹配任何十进制数,它相当于类[0-9]\D匹配任何非数字字符,它相当于类[^0-9]\s匹配任何空白字符,它相当于类[\t\n\r\f\v]\S匹配任何非空白字符,它相当于类[^\t\n\r\f\v]\w匹配任何字母数字字符,它相当于类[a-zA-Z0-9_]\W匹配任何非字母数字字符,它相当于类[^a-zA-Z0-9_]2024/11/1710.2简单模式10.2.2重复正则表达式的另一个功能是可以指定正则表达式的某一部分的重复次数。我们讨论的第一个具有重复功能的元字符是“*”。“*”并不匹配字符“*”,它表示前一个字符可以被匹配任意次数,包括零次。例如,“ca*t”将匹配“ct”(0个“a”字符),“cat”(1个“a”字符),“caaat”(3个“a”字符)等。2024/11/1710.2简单模式10.2.2重复像“*”这样的重复我们称作是贪婪的(Greedy)。当重复一个正则表达式时,匹配引擎会试图重复尽可能多的次数。如果模式的后面部分没有被匹配,匹配引擎将退回并再次尝试更小的重复。例如,模式“a[bcd]*b”。它首先匹配字母“a”,然后零个或更多个来自字符类[bcd]中的字母,最后以“b”结尾。现在考虑该正则表达式对字符串“abcbd”的匹配。匹配过程如下表所示:2024/11/1710.2简单模式步

骤匹配字符注

解1a匹配正则表达式中的“a”2abcbd引擎尽可能多地匹配[bcd]中的字符,这里匹配到字符串的结尾3失败引擎尝试匹配“b”,但当前位置已经是字符的最后了,所以失败4abcb退回,[bcd]*尝试少匹配一个字符5失败再次尝次匹配b,但在当前最后一位字符是“d”6abc再次退回,[bcd]*只匹配“bc”7abcb再次尝试匹配“b”,当前位置上的字符正好是“b”,匹配成功2024/11/1710.2简单模式10.2.2重复另一个重复元字符是+,表示匹配一次或更多次,注意+要求所匹配的字符至少出现一次。“ca+t”就可以匹配“cat”(1个“a”),“caaat”(3个“a”),但“ct”不能匹配。还有一些表示重复的元定符。问号?表示匹配一次或零次,我们可以将它用于标识某字符是可选的。例如:“high-?tech”匹配“high-tech”或“hightech”。最复杂的重复限定符是{m,n},其中m和n是十进制整数。{m,n}表示某个匹配项至少需要重复m次,但不能超过n次。例如,a/{1,2}b可以匹配a/b和a//b,但不能匹配ab与a///b。可以省略m和n中的任意一个,省略m表示重复下限为0,而省略n则表示重复上限为无穷。目录2024/11/17210.1正则表达式简介10.2简单模式10.3使用正则表达式10.4更多模式功能10.5修改字符串10.6常见问题2024/11/1710.3使用正则表达式10.3.1

编译正则表达式Python中通过re模块提供了一个正则表达式引擎的接口,利用这个接口,我们可以将正则表达式编译成对象并用它们来进行匹配。正则表达式被编译成正则表达式对象(RegularExpressionObjects),可以为不同的操作提供方法,如模式匹配搜索或字符串替换。使用如下代码编译正则表达式对象:

>>>importre>>>p=pile('ab*')>>>ppile('ab*')2024/11/1710.3使用正则表达式10.3.2反斜杠带来的问题则表达式用反斜杠字符“\”来表示特殊格式或在不触发其特殊方法的情况下使用特殊字符。这就与Python在字符串中起相同作用的反斜杠字符产生了冲突。例如,为了匹配字符串“\section”,正则表达式需要在所有反斜杠字符和其他元字符前添加反斜杠来取消其特殊意义,即要匹配的字符串在程序中应该写成“\\section”。当把这个字符串作为参数传传递给pile()时必须还是“\\section”。作为Python的字符串值,“\\section”中的两个反斜杠还要再次使用反斜杠取消特殊意义,最后结果就变成了“\\\\section”。也就是说,为了匹配一个反斜杠,必须在正则表达式字符串中写四个反斜杠,导致输入大量重复的反斜杠,而且所生成的字符串也很难理解。2024/11/1710.3使用正则表达式10.3.2反斜杠带来的问题解决的办法就是为正则表达式使用Python的原始(raw)字符串表示,在字符串前加上字符“r”,反斜杠就不会被任何特殊方式处理,所以r"\n"就包含“\”和“n”的两个字符,而“\n”则表示一个字符,即换行。正则表达式在Python代码中通常都是用这种原始字符串表示。如果想要匹配字符串“\section”,其原始字符串的表示法应为:r"\\section"。2024/11/1710.3使用正则表达式10.3.3执行匹配下表给出了正则表达式对象几个最常用的方法:方

法目

的match()判断从字符串开头是否匹配正则表达式search()搜索整个字符串,找到正则表达式匹配的位置findall()找到所有匹配正则表达式的子串,并将它们作为一个列表返回finditer()找到所有匹配正则表达式的子串,并将它们作为一个迭代器返回2024/11/1710.3使用正则表达式10.3.3执行匹配如果匹配失败,match()和search()将返回None。如果匹配成功,就会返回一个match对象的实例,其中有此次匹配的信息:比如,匹配是从哪里开始在哪里结束,所匹配的子串等。match对象中重要的方法如下表所示:方

法目

的group()返回匹配正则表达式的字符串start()返回匹配字符串开始的位置end()返回匹配字符串结束的位置span()返回一个包含开始和结束位置的元组2024/11/1710.3使用正则表达式10.3.4模块级函数re模块提供了顶级函数调用,例如match()、search()、sub()等。没有必要先创建一个正则表达式对象,再调用它的方法。这些函数使用正则表达式字符串作为第一个参数,而后面的参数则与相应正则表达式对象的方法参数相同,返回则要么是None,要么是一个match对象的实例。2024/11/1710.3使用正则表达式10.3.5编译标志使用编译标志可以修改正则表达式的一些运行方式。在re模块中编译标志可以使用两种形式表示,一是如同IGNORECASE的全名,另一种是一个字母的缩写形式,例如IGNORECASE缩写为I。多个标志可以通过使用或符号“|”来分隔,如“re.I|re.M”表示同时设置I和M标志,该标志在编译正则表达式对象时,以参数的形式输入。2024/11/1710.3使用正则表达式10.3.5编译标志标

志含

义ASCII,A使\w,\b等只匹配ASCII字符DOTALL,S使字符“.”匹配任意字符,包括换行符IGNORECASE,I使匹配对大小写不敏感LOCALE,L做本地化识别(locale-aware)匹配MULTILINE,M多行匹配,会影响VERBOSE,X能够使用正则表达式的verbose状态,使之更加清晰易懂Python正则表达式的编译标志由下表所示:目录2024/11/17210.1正则表达式简介10.2简单模式10.3使用正则表达式10.4更多模式功能10.5修改字符串10.6常见问题2024/11/1710.4更多模式功能10.4.1其他元字符零宽界定符(Zero-WidthAssertions),包括\b和\B。\b表示单词边界。这是个零宽界定符,用以匹配单词的开头和结尾。之所以被称为零宽界定符,是因为它们如字面意思一样没有“宽度”,在正则表达式中,通常一个字符应对应匹配文本中的一个或数个字符,但零宽界定符不匹配任何字符。例如只匹配“class”整个单词;而当它被包含在其他单词中时不匹配,正则表达式可以写成:r"\bclass\b"在Python字符串里,“\b”是回退符,使用原始字符串避免冲突。“\B”作用正好同“\b”相反,只在当前位置不是单词边界时才匹配。2024/11/1710.4更多模式功能10.4.1其他元字符“|”为“或”操作符,如果A和B均为正则表达式,那么A|B将匹配任何匹配了A或B的字符串。“Jump|Run”将匹配字符串“Jump”或“Run”。“^”用于匹配行首,除非设置了MULTILINE标志,否则只匹配字符串开头的部分。设置了MULTILINE标志后,^可以匹配每一行的开头。如果需要匹配在一行开头的“From”字符串,正则表达式可以写成“^From”。“$”与“^”正好相反,用于匹配行尾的字符串,行尾表示是一个字符串的结尾,或者任何后面紧跟着一个换行符的位置。2024/11/1710.4更多模式功能10.4.2分组正则表达式也常用来分析字符串,我们可以编写一个正则表达式,匹配字符串中感兴趣的部分,并将其分成几个组(Group)。分组是通过括号“(”和“)”元字符来标识的。位于它们之中的表达式组成一组例如,我们可以用重复限制符,例如*、+、?以及{m,n}来重复组里的内容。比如(ab)*将匹配零或多个重复的“ab”:

>>>p=pile('(ab)*')>>>print(p.match('ababababab').span())(0,10)

分组总是从0开始计数的,而且第0组总是存在的,它就是不显式地使用分组时正则表达式所匹配的字符串,上述match对象的方法都把第0组作为它们的缺省参数。2024/11/1710.4更多模式功能10.4.2分组通过分组方法获得的小组(Subgroups)是从1开始从左向右计数的。组可以被嵌套,计数的值可以通过从左向右计算括号“(”的数目来确定,第0组即group(0)是一个特殊的组,它是不采取分组时,正则表达式所匹配的字符串2024/11/1710.4更多模式功能10.4.2分组一个匹配模式中的逆向引用(Backreferences)允许我们指定一个先前分组所获得的内容,并且该内容在当前位置也能找到。用法为反斜杠后紧跟一个分组号。例如,我们有一个逆向引用“\1”,用于指定分组1,假设分组1的内容为一个单词“book”,如果在逆向应用出现的位置正好也是单词“book”,那这个匹配就会成功,否则失败。例如,下面的正则表达式会找出在字符串中被连续输入了两次的单词:

>>>p=pile(r'(\b\w+)\s+\1')>>>p.search('Findthethebook').group()'thethe'2024/11/1710.4更多模式功能10.4.3无捕获组和命名组正则表达式会使用很多组,既可以捕获我们感兴趣的子串,又可以分组和结构化表达式本身。在复杂的正则表达式中,追踪组号将变得困难。“无捕获组”与“命名组”这两个功能可以对这个问题有所帮助。它们也都使用正则表达式扩展的通用语法。紧跟在问号后面的字符说明了扩展的内容,例如“(?=foo)”表示一个肯定前向界定符,而“?:foo”则是要讨论的无捕获组。2024/11/1710.4更多模式功能10.4.3无捕获组和命名组当我们想用一个组代表正则表达式的一部分,但又对获取组中的内容不感兴趣时可以使用一个无捕获组(Non-capturinggroup)——“(?:…)”来实现这项功能,括号中的“…”被替换成需要的正则表达式:

>>>m=re.match("([abc])+","abc")>>>m.groups()('c',)>>>m=re.match("(?:[abc])+","abc")>>>m.groups()()

当不使用无捕获组时,m的groups()方法返回分组1,其内容为字符“c”,而当使用无捕获组后,返回分组中将不会有任何内容。2024/11/1710.4更多模式功能10.4.3无捕获组和命名组另一个扩展功能是命名组(NamedGroups),与通常使用数字引用分组不同的是,它可以用一个名字来引用分组。命名组表示为:(?P<name>…),尖括号中的文本即为组的名字,命名组的行为与捕获组是相同的。当对命名组使用match对象的方法时,既可以用表示组号的整数作为参数,也可以用包含组名的字符串作为参数,所以我们可以通过两种方式来得到一个分组中的信息。2024/11/1710.4更多模式功能10.4.3无捕获组和命名组使用命名可以是我们用容易记住的名字而不是难以记住数字来引用分组例如:

InternalDate=pile(r'INTERNALDATE"' r'(?P<day>[123][0-9])-(?P<mon>[A-Z][a-z][a-z])-' r'(?P<year>[0-9][0-9][0-9][0-9])'r'(?P<hour>[0-9][0-9]):( ?P<min>[0-9][0-9]):(?P<sec>[0-9][0-9])'r'(?P<zonen>[-+])( ?P<zoneh>[0-9][0-9])(?P<zonem>[0-9][0-9])'r'"')

使用分组名zonem来获取分组内容要比记住编号9来获取分组容易得多。在逆向引用的语法中,也可以使用组名代替组号。引用组名的格式为:(?P=name),表示在当前位置,名称为name的组的内容再次重现。2024/11/1710.4更多模式功能10.4.4前向界定符另外一个零宽界定符是前向界定符,或称为前向断言(LookaheadAssertions)。前向界定符有两种形式—肯定(Positive)前向界定符和否定(Negative)前向界定符。(?=pattern)是一个肯定前向界定符,而(?!pattern)是一个否定前向界定符。其中的“pattern”是一个正则表达式,代表某个匹配模式。与通常的匹配模式不同的是,它只返回匹配的结果—成功或不成功,而不会引起正则表达式引擎的向前移动。换句话说,前向界定符不会“消耗”字符,而只是判断该位置是否匹配。肯定前向界定符在当前位置能够匹配返回匹配成功,否则失败。2024/11/1710.4更多模式功能10.4.4前向界定符例如,如果对“aregularexpression”这个字符串,我们只想匹配“regular”中的“re”,而不想匹配“expression”中的“re”,那么可以这样写正则表达式:re(?=gular)。这表示,当“re”之后紧跟的字符串是“gular”才能匹配。目录2024/11/17210.1正则表达式简介10.2简单模式10.3使用正则表达式10.4更多模式功能10.5修改字符串10.6常见问题2024/11/1710.5修改字符串除了简单地搜索了一个静态字符串外,正则表达式对象也含有一些方法用于修改字符串。如下表所示方

法目

的split()字符串分片,返回一个列表(List),分隔的位置为表达式匹配的地方sub()替换所有正则表达式匹配的子串subn()与sub()功能相同,但会返回新的字符串和替换字串的数量2024/11/1710.5修改字符串10.5.1字符串分片正则表达式对象的split()方法在正则表达式匹配的地方将字符串分片,并返回一个包含分片列表。它同字符串的split()方法相似,但通过正则表达式可以提供更多的分隔符。而字符串的split()方法只支持空白符和固定字符串。Python同样也有一个模块级的re.split()函数。split()方法的原型如下。

split(string[,maxsplit=0])可以通过设置maxsplit的值来限制分片数,当maxsplit非零时,最多只能有maxsplit+1个分片,字符串的其余部分被作为列表的最后一个元素返回。2024/11/1710.5修改字符串10.5.2搜索与替换下面是一个使用sub()方法的简单例子,使用单词“color”来替换具体的颜色名:>>>p=pile('(blue|white|red)')>>>p.sub('color','bluesocksandredshoes')'colorsocksandcolorshoes'>>>p.sub('color','bluesocksandredshoes',count=1)'colorsocksandredshoes'

subn()方法作用一样,但返回的是一个包含新字符串和替换执行次数的元组。

>>>p=pile('(blue|white|red)')>>>p.subn('color','bluesocksandredshoes')('colorsocksandcolorshoes',2)>>>p.subn('color','nocolorsatall')('nocolorsatall',0)2024/11/1710.5修改字符串10.5.2搜索与替换如果替换值是一个字符串,那么任何在其中的反斜杠都会被处理。比如“\n”将会被转换成一个换行符,“\r”转换成回车等等。未知的转义字符如“\j”则保持原样。逆向引用,如“\2”,被正则表达式中相应的组所匹配的子串替换,这样可以在替换后的字符串中插入原始文本的一部分。下面的例

温馨提示

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

评论

0/150

提交评论