python正则表达式学

时间:2022-04-07 02:41:43

FBI WARNING:本人新手,高手勿喷。百度上这些资料很多,写它的目的纯粹是为了记录。

一.什么是字符串匹配

字符串匹配的过程其实就是检测某字符串是否满足某格式,比如 " abc " 匹配了 "都是字母" 和 "都是小写字母"两种格式,当然,在实际程序中,这些格式不能用自然的语言表达,所以有了正则表达式来描述这些格式。

二.python正则表达式

开始之前,必然要配置好python的各种环境,我用的是python2.7.6

本文统一用python的search函数作试验

新建py脚本,第一句写上

<pre name="code" class="python">'''python正则表达式学习'''
import re
 
然后是re.search函数,其作用就是从字符串中寻找匹配的那一部分,并返回 

接下来介绍正则表达式的各种通配符,看代码比较实在


1.   ^  

<pre name="code" class="python">line = 'abcdefg'
searchObj = re.search( '^abc' , line ) #第一个参数为正则表达式,第二个是被搜索的字符串
#^用于检测字符串开头如果字符串的开头匹配,则返回匹配的那部分
print searchObj.group(0) #返回abc,虽然line匹配^abc但只返回匹配的那部分,即abc
searchObj = re.search( '^bc' , line )
print searchObj.group(0) #报错,因为searchObj为空,虽然line字串有'bc'但'^bc'只匹配bc开头的字符串
 
 

2.   $ 和^相似,用于匹配字符串末尾,正则表达式写法,如 'fg$' 匹配上面的line

以下省略re.search,print等语句,仅写出正则表达式和匹配结果,没有特殊声明时,被匹配的字符串为line

3.   .  用于代表除换行符外所有的字符

line = 'abcdefg'
        '.cd'  --->匹配line中的bcd,只会返回bcd

    ‘.ab’ ---->不匹配,因为line中的ab前面已经没有字符了,.不能代表空字符

    '$...' ---->匹配line中的abc(3个点就是3个字符),返回abc


    4.   [  ]    用于代表一个字符,如[abc]代表a或b或c,但只能代表其中一个字符(而不是字符串)

     ‘[abc]’  --->含a或b或c的字符串匹配,seachObj找到第一个匹配的字符串后就会返回,故line中匹配的有a,b,c,但只---->返回a

    ‘^[abc]’ ---->a,b,c开头的字符串都匹配,故匹配,且还是返回a

    

    5.   [^  ]   也是代表一个字符,但与上面相反,代表不在中括号里的其它字符

    '[^abc]'  ---->含有非a,b,c的字符就可以匹配,故还是匹配,返回第一个非a,b,c的字符d

    ‘^[^abc]’  ----->a,b,c开头的字符串都不匹配,故不匹配


    6. re */+/? --->re代表一个字符或者带括号的正则表达式 *代表0或连续多个匹配re,+代表1或连续多个匹配re,?代表0或1个匹配re,这里涉及到一个贪婪的问题,一并讨论了

    用于匹配的字符串 'cbcbaaababb'

    这三个符号仅表示该符号前一个字符的数量,如

    'ct*'  ------>匹配,c是匹配的,t不匹配,但是*代表0个也是匹配的,故返回c

    'cb+'  ---->匹配,但返回的是cb,而不是cbcb,因为+代表的不是cb的数量,而是b的数量(1个或连续多个)

    想返回cbcb,可以加括号:

    ‘(cb)+’  ---->匹配,此时cb被当成一个整体,+代表着cb的数量

    但是很奇怪,+代表的是含有1个或连续多个,那么按理说cb和cbcb都是匹配的,那么python选择谁作返回呢?

   答案是cbcb,python选择最长的返回,这就是所谓的贪婪,如:

   ‘a*’ ---->匹配,没有a或a,aa,aaa均匹配,但是python选择了最长的aaa

   这三个里面*和+有贪婪的特性,?是没有的:

   'a?' ----->0个或1个a都匹配,但返回的是0个a

   为了避免*和+的贪婪,可以选择使用*?和+?,python将会选取*或+的最短的匹配返回:

   'a*?'  ---->匹配,返回空串

   'a+?'  ----->匹配,返回1个a


   7.  re {m}/{m,}/{m,n}  连续m次/m次或m以上次/m-n次匹配re,这里也有贪婪的问题

   用于匹配的字符串 'cbcbaaababb'

     ‘cb{2}’ ---->不匹配,应该匹配的是cbb

   '(cb){2}'  ----->匹配,匹配cbcb

   'a{1,}'  ----->匹配,a,aa,aaa都匹配,贪婪模式选择了aaa返回

   'a{1,}?'  ------>匹配,抑制贪婪,返回a

   ‘a{1,2}’  ----->匹配,a,aa都匹配,由于贪婪,返回aa

   'a{1,2}?' ----->匹配,抑制贪婪,返回a


   8. |   类似[ ]

   9.  \w 和 \W

   \w 代表a-z,A-Z,0-9,以及下划线

   \W 代表非\w指代的字符(包括换行符等空白字符)

   'a\wb'  --->可以匹配abc,adc,a_c等

   'a\Wb' --->可以匹配a c,a!c等

   这里有一个需要注意的特例,也是笔者认为奇怪的地方(python2.7.6):

   <1>被匹配的字符串'abc!!!'

   '(\w)*'   ----->可以匹配,返回'abc'

   '(\W)*' ---->也可以匹配,却返回空字符串!(若不是以非单词符号开头,则匹配空字符串,因为*也可以表示0个)

   <2>被匹配的字符串换成'!!!abc'

   '(\w)*'   ------>可以匹配,却返回空字符串(理解成若不是以单词符号开头,则匹配空字符串,因为*也可以表示0个)

   '(\W)*'   ------>可以匹配,返回'!!!'

   

    根据<1>和<2>发现,‘(\w)*’和'(\W)*' 匹配字符串的规律如上面红色字体所注,而'(\w)+'就不会出现奇怪的现象,因为'+'至少为1


待更新....