2022年Python正则式学习笔记 .pdf
《2022年Python正则式学习笔记 .pdf》由会员分享,可在线阅读,更多相关《2022年Python正则式学习笔记 .pdf(24页珍藏版)》请在淘文阁 - 分享文档赚钱的网站上搜索。
1、1 Python正则式的基本用法1.1基本规则1.2重复1.2.1最小匹配与精确匹配1.3前向界定与后向界定1.4组的基本知识2 re 模块的基本函数2.1使用 compile 加速2.2 match和 search2.3 finditer2.4 字符串的修改与替换3 更深入的了解 re 的组与对象3.1编译后的 Pattern对象3.2 组与 Match 对象3.2.1 组的名字与序号3.2.2 Match对象的方法4 更多的资料名师资料总结-精品资料欢迎下载-名师精心整理-第 1 页,共 24 页 -初学 Python,对 Python 的文字处理能力有很深的印象,除了str 对象自带的一
2、些方法外,就是正则表达式这个强大的模块了。但是对于初学者来说,要用好这个功能还是有点难度,我花了好长时间才摸出了点门道。由于我记性不好,很容易就忘事,所以还是写下来比较好一些,同时也可以加深印象,整理思路。由于我是初学,所以肯定会有些错误,还望高手不吝赐教,指出我的错误。1 Python正则式的基本用法Python的正则表达式的模块是,re?,它的基本语法规则就是指定一个字符序列,比如你要在一个字符串s=?123abc456?中查找字符串?abc?,只要这样写:import re s=123abc456eabc789 re.findall(r?abc?,s)结果就是:abc,abc 这里用到的
3、函数”findall(rule,target,flag)”是个比较直观的函数,就是在目标字符串中查找符合规则的字符串。第一个参数是规则,第二个参数是目标字符串,后面还可以跟一个规则选项(选项功能将在compile 函数的说明中详细说明)。返回结果结果是一个 列表,中间存放的是符合规则的字符串。如果没有符合规则的字符串被找到,就返回一个空列表。为什么要用r.字符串(raw 字符串)?由于正则式的规则也是由一个字符串定义的,而在正则式中大量使用转义字符/,如果不用raw 字符串,则在需要写一个/的地方,你必须得写成/,那么在要从目标字符串中匹配一个/的时候,你就得写上4 个/成为/!这当然很麻烦,
4、也不直观,所以一般都使用r来定义规则字符串。当然,某些情况下,可能不用raw 字符串比较好。以上是个最简单的例子。当然实际中这么简单的用法几乎没有意义。为了实现复杂的规则查找,re规定了若干语法规则。它们分为这么几类:功能字符:,.?,*?,+?,|?,?,?,$?,/?等,它们有特殊的功能含义。特别是?/?字符,它是转义引导符号,跟在它后面的字符一般有特殊的含义。规则分界符:,?,(?,)?,?等,也就是几种括号了。预定义转义字符集:“/d”“/w”“/s”等等,它们是以字符?/?开头,后面接一个特定字符的形式,用来指示一个预定义好的含义。名师资料总结-精品资料欢迎下载-名师精心整理-第 2
5、 页,共 24 页 -其它特殊功能字符:?#?,!?,:?,-,等,它们只在特定的情况下表示特殊的含义,比如(?#)就表示一个注释,里面的内容会被忽略。下面来一个一个的说明这些规则的含义,不过说明的顺序并不是按照上面的顺序来的,而是我认为由浅入深,由基本到复杂的顺序来编排的。同时为了直观,在说明的过程中尽量多举些例子以方便理解。1.1 基本规则 字符集合设定符首先说明一下字符集合设定的方法。由一对方括号括起来的字符,表明一个字符集合,能够匹配包含在其中的任意一个字符。比如 abc123,表明字符?a?,b?,c?,1?,2?,3?都符合它的要求。可以被匹配。在?,?中还可以通过?-,减号来指定
6、一个字符集合的范围,比如可以用a-zA-Z 来指定所以英文字母的大小写,因为英文字母是按照从小到大的顺序来排的。你不可以把大小的顺序颠倒了,比如写成z-a就不对了。如果在?,?里面的开头写一个,?号,则表示取非,即在括号里的字符都不匹配。如 a-zA-Z 表明不匹配所有英文字母。但是如果,?不在开头,则它就不再是表示取非,而表示其本身,如a-zA-Z 表明匹配所有的英文字母和字符?。|或规则将两个规则并列起来,以|连接,表示只要满足其中之一就可以匹配。比如a-zA-Z|0-9 表示满足数字或字母就可以匹配,这个规则等价于a-zA-Z0-9注意:关于?|?要注意两点:第一,它在?,?之中不再表示
7、或,而表示他本身的字符。如果要在?,?外面表示一个?|?字符,必须用反斜杠引导,即?/|?;第二,它的有效范围是它两边的整条规则,比如 dog|cat?匹配的是 dog?和?cat?,而不是?g?和?c?。如果想限定它的有效范围,必需使用一个无捕获组,(?:)?包起来。比如要匹配I have a dog?或?I have a cat?,需要写成 r?I have a(?:dog|cat)?,而不能写成r?I have a dog|cat?例名师资料总结-精品资料欢迎下载-名师精心整理-第 3 页,共 24 页 -s=,I have a dog,I have a cat?re.findall(r
8、?I have a(?:dog|cat)?,s)I have a dog,I have a cat#正如我们所要的下面再看看不用无捕获组会是什么后果:re.findall(r?I have a dog|cat?,s)I have a dog,cat#它将?I have a dog?和?cat?当成两个规则了至于无捕获组的使用,后面将仔细说明。这里先跳过。.匹配所有字符匹配除换行符?/n?外的所有字符。如果使用了?S?选项,匹配包括?/n?的所有字符。例:s=?123/n456/n789?findall(r,.+?,s)123,456,789 re.findall(r,.+?,s,re.S)12
9、3/n456/n789和$匹配字符串开头和结尾注意?不能在 中,否则含意就发生变化,具体请看上面的?,?说明。在多行模式下,它们可以匹配每一行的行首和行尾。具体请看后面compile 函数说明的?M?选项部分/d 匹配数字这是一个以?/?开头的转义字符,?/d?表示匹配一个数字,即等价于0-9/D 匹配非数字这个是上面的反集,即匹配一个非数字的字符,等价于0-9。注意它们的大小写。下面我们还将看到Python的正则规则中很多转义字符的大小写形式,代表互补的关系。这样很好记。/w 匹配字母和数字名师资料总结-精品资料欢迎下载-名师精心整理-第 4 页,共 24 页 -匹配所有的英文字母和数字,即
10、等价于a-zA-Z0-9。/W 匹配非英文字母和数字即?/w?的补集,等价于 a-zA-Z0-9。/s 匹配间隔符即匹配空格符、制表符、回车符等表示分隔意义的字符,它等价于 /t/r/n/f/v。(注意最前面有个空格)/S 匹配非间隔符即间隔符的补集,等价于 /t/r/n/f/v/A 匹配字符串开头匹配字符串的开头。它和?的区别是,?/A?只匹配整个字符串的开头,即使在?M?模式下,它也不会匹配其它行的很首。/Z 匹配字符串结尾匹配字符串的结尾。它和?$?的区别是,?/Z?只匹配整个字符串的结尾,即使在?M?模式下,它也不会匹配其它各行的行尾。例:s=12 34/n56 78/n90 re.f
11、indall(r/d+,s,re.M)#匹配位于行首的数字12,56,90 re.findall(r?/A/d+?,s,re.M)#匹配位于字符串开头的数字12 re.findall(r/d+$,s,re.M)#匹配位于行尾的数字34,78,90 re.findall(r?/d+/Z?,s,re.M)#匹配位于字符串尾的数字90/b 匹配单词边界它匹配一个单词的边界,比如空格等,不过它是一个0长度字符,它匹配完的字符串不会包括那个分界的字符。而如果用?/s?来匹配的话,则匹配出的字符串中会包含那个分界符。例:名师资料总结-精品资料欢迎下载-名师精心整理-第 5 页,共 24 页 -s=abc
12、abcde bc bcd re.findall(r?/bbc/b?,s)#匹配一个单独的单词,bc?,而当它是其它单词的一部分的时候不匹配bc 只找到了那个单独的?bc?re.findall(r?/sbc/s?,s)匹配一个单独的单词,bc?bc#只找到那个单独的?bc?,不过注意前后有两个空格,可能有点看不清楚/B 匹配非边界和?/b?相反,它只匹配非边界的字符。它同样是个0 长度字符。接上例:re.findall(r?/Bbc/w+?,s)#匹配包含?bc?但不以?bc?为开头的单词bcde#成功匹配了?abcde?中的?bcde?,而没有匹配?bcd?(?:)无捕获组当你要将一部分规则作
13、为一个整体对它进行某些操作,比如指定其重复次数时,你需要将这部分规则用?(?:?,)?把它包围起来,而不能仅仅只用一对括号,那样将得到绝对出人意料的结果。例:匹配字符串中重复的?ab?s=?ababab abbabb aabaab?re.findall(r?/b(?:ab)+/b?,s)ababab如果仅使用一对括号,看看会是什么结果:re.findall(r?/b(ab)+/b?,s)ab这是因为如果只使用一对括号,那么这就成为了一个组(group)。组的使用比较复杂,将在后面详细讲解。(?#)注释Python允许你在正则表达式中写入注释,在?(?#?,)?之间的内容将被忽略。(?iLmsu
14、x)编译选项指定名师资料总结-精品资料欢迎下载-名师精心整理-第 6 页,共 24 页 -Python的正则式可以指定一些选项,这个选项可以写在findall 或 compile 的参数中,也可以写在正则式里,成为正则式的一部分。这在某些情况下会便利一些。具体的选项含义请看后面的compile 函数的说明。此处编译选项?i?等价于 IGNORECASE,L 等价于 LOCAL,m 等价于MULTILINE,s 等价于 DOTALL,u 等价于 UNICODE,x 等价于VERBOSE。请注意它们的大小写。在使用时可以只指定一部分,比如只指定忽略大小写,可写为,(?i)?,要同时忽略大小写并使用
15、多行模式,可以写为,(?im)?。另外要注意选项的有效范围是整条规则,即写在规则的任何地方,选项都会对全部整条正则式有效。1.2 重复正则式需要匹配不定长的字符串,那就一定需要表示重复的指示符。Python的正则式表示重复的功能很丰富灵活。重复规则的一般的形式是在一条字符规则后面紧跟一个表示重复次数的规则,已表明需要重复前面的规则一定的次数。重复规则有:*0 或多次匹配表示匹配前面的规则0 次或多次。+1 次或多次匹配表示匹配前面的规则至少1 次,可以多次匹配例:匹配以下字符串中的前一部分是字母,后一部分是数字或没有的变量名字 s=,aaa bbb111 cc22cc 33dd,re.find
16、all(r?/ba-z+/d*/b?,s)#必须至少 1 个字母开头,以连续数字结尾或没有数字aaa,bbb111注意上例中规则前后加了表示单词边界的?/b?指示符,如果不加的话结果就会变成:re.findall(r?a-z+/d*?,s)aaa,bbb111,cc22,cc,dd#把单词给拆开了大多数情况下这不是我们期望的结果。名师资料总结-精品资料欢迎下载-名师精心整理-第 7 页,共 24 页 -?0 或 1 次匹配只匹配前面的规则0 次或 1 次。例,匹配一个数字,这个数字可以是一个整数,也可以是一个科学计数法记录的数字,比如 123和 10e3都是正确的数字。s=,123 10e3
17、20e4e4 30ee5,re.findall(r?/b/d+eE?/d*/b?,s)123,10e3它正确匹配了 123和 10e3,正是我们期望的。注意前后的?/b?的使用,否则将得到不期望的结果。1.2.1 精确匹配和最小匹配Python正则式还可以精确指定匹配的次数。指定的方式是m精确匹配 m 次m,n 匹配最少 m 次,最多 n 次。(nm)如果你只想指定一个最少次数或只指定一个最多次数,你可以把另外一个参数空起来。比如你想指定最少3 次,可以写成3,(注意那个逗号),同样如果只想指定最大为5 次,可以写成 ,5,也可以写成 0,5。例 寻找下面字符串中a:3 位数b:2 位数到 4
18、 位数c:5 位数以上的数d:4 位数以下的数 s=,1 22 333 4444 55555 666666,re.findall(r?/b/d3/b?,s)#a:3 位数333 re.findall(r?/b/d2,4/b?,s)#b:2 位数到 4 位数22,333,4444 re.findall(r?/b/d5,/b?,s)#c:5位数以上的数55555,666666 re.findall(r?/b/d1,4/b?,s)#4 位数以下的数1,22,333,4444名师资料总结-精品资料欢迎下载-名师精心整理-第 8 页,共 24 页 -*?+?最小匹配,*?,+?,?通常都是尽可能多的匹配
19、字符。有时候我们希望它尽可能少的匹配。比如一个 c 语言的注释,/*part 1*/*part 2*/?,如果使用最大规则:s=r,/*part 1*/code/*part 2*/?re.findall(r?/*.*/*/?,s),/*part 1*/code/*part 2*/?结果把整个字符串都包括进去了。如果把规则改写成 re.findall(r?/*.*?/*/?,s)#在*后面加上?,表示尽可能少的匹配/*part 1*/,/*part 2*/结果正确的匹配出了注释里的内容1.3 前向界定与后向界定有时候需要匹配一个跟在特定内容后面的或者在特定内容前面的字符串,Python提供一个简
20、便的前向界定和后向界定功能,或者叫前导指定和跟从指定功能。它们是:(?s=r?/*comment 1*/code/*comment 2*/?re.findall(r?(?s=,aaa111aaa,bbb222,333ccc,re.findall(r?(?re.findall(r?/d+(?=a-z+)?,s)111,333如果你一定要匹配包夹在字母中间的数字,你可以使用组(group)的方式 re.findall(ra-z+(/d+)a-z+,s)111组的使用将在后面详细讲解。除了前向界定前向界定和后向界定外,还有前向非界定和后向非界定,它的写法为:(?re.findall(r?/d+(?!
21、/w+)?,s)222注意这里我们使用了/w 而不是像上面那样用 a-z,因为如果这样写的话,结果会是:re.findall(r?/d+(?!a-z+)?,s)11,222,33这和我们期望的似乎有点不一样。它的原因,是因为?111?和?222?中的前两个数字也是满足这个要求的。因此可看出,正则式的使用还是要相当小心的,因为我开始就是这样写的,看到结果后才明白过来。不过Python试验起来很方便,这也是脚本语言的一大优点,可以一步一步的试验,快速得到结果,而不用经过烦琐的编译、链接过程。也因此学习Python就要多试,跌跌撞撞的走过来,虽然曲折,却也很有乐趣。1.4 组的基本知识名师资料总结-
22、精品资料欢迎下载-名师精心整理-第 10 页,共 24 页 -上面我们已经看过了Python的正则式的很多基本用法。不过如果仅仅是上面那些规则的话,还是有很多情况下会非常麻烦,比如上面在讲前向界定和后向界定时,取夹在字母中间的数字的例子。用前面讲过的规则都很难达到目的,但是用了组以后就很简单了。()无命名组最基本的组是由一对圆括号括起来的正则式。比如上面匹配包夹在字母中间的数字的例子中使用的(/d+),我们再回顾一下这个例子:s=,aaa111aaa,bbb222,333ccc,re.findall(ra-z+(/d+)a-z+,s)111可以看到 findall 函数只返回了包含在()中的内
23、容,而虽然前面和后面的内容都匹配成功了,却并不包含在结果中。除了最基本的形式外,我们还可以给组起个名字,它的形式是(?P)命名组,(?P?代表这是一个 Python 的语法扩展?里面是你给这个组起的名字,比如你可以给一个全部由数字组成的组叫做?num?,它的形式就是?(?P/d+)?。起了名字之后,我们就可以在后面的正则式中通过名字调用这个组,它的形式是(?P=name)调用已匹配的命名组要注意,再次调用的这个组是已被匹配的组,也就是说它里面的内容是和前面命名组里的内容是一样的。我们可以看更多的例子:请注意下面这个字符串各子串的特点。s=aaa111aaa,bbb222,333ccc,444d
24、dd444,555eee666,fff777ggg我们看看下面的正则式会返回什么样的结果:re.findall(r(a-z+)/d+(a-z+),s)#找出中间夹有数字的字母(aaa,aaa),(fff,ggg)re.findall(r(?Pa-z+)/d+(?P=g1),s)#找出被中间夹有数字的前后同样的字母aaa re.findall(ra-z+(/d+)(a-z+),s)#找出前面有字母引导,中间是数字,后面是字母的字符串中的中间的数字和后面的字母(111,aaa),(777,ggg)名师资料总结-精品资料欢迎下载-名师精心整理-第 11 页,共 24 页 -我们可以通过命名组的名字在
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 2022年Python正则式学习笔记 2022 Python 正则 学习 笔记
限制150内