正则表达式re模块

Posted FuZZ

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式re模块相关的知识,希望对你有一定的参考价值。

正则表达式模块re

1. 正则简介

就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言,
(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被
编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

2.正则匹配之字符匹配

  • 普通子符匹配 大多数字符和字母都会和自身匹配
>>> s = "this is myblogs ,1 2 ,34"
>>> re.findall(is,s)
[is, is]
>>> re.findall(2,s)
[2]

 

  • 二元字符匹配

    • 常用元字符:

      • . 匹配任意字符,除了换行符,当re.DOTALL标记被指定时,则可以匹配包括换行符的任意字符
      • ^ 匹配起始位置
      • $ 匹配终止位置
      • * 匹配前面的字符0到多次,可以没有
      • + 匹配前面的字符1到多次,最少有一个
      • ? 匹配前面的字符0-1次
      • \ 转义符 反斜杠后面跟元字符去除特殊功能, 反斜杠后面跟普通字母实现特殊功能
      • {} 匹配次数 如 {3}匹配3次,{1,5} 匹配1到五次
      • [] 或的作用 a[bc]d 匹配 abd acd ,除了-,非^,"" 里面的特殊符号没有任何意义
    • 具体使用:

>>> s = "this is myblogs , my name is blogs"
# . 表示任意字符,通用匹配
>>> re.findall(.s,s)    #使用.匹配任意以s结尾的两位字符串
[is, is, gs, is, gs]
>>> re.findall(.blogs,s)
[yblogs,  blogs]
>>> re.findall(b.og,s)
[blog, blog]

# ^ 表示匹配开头,只匹配开头内容
>>> re.findall(^is,s)
[]
>>> re.findall(^th,s)
[th]
>>> re.findall(^this,s)
[this]

# $表示匹配结尾内容,只匹配结尾,用在字符之后
>>> re.findall($s,s)      #注意$要放字符串后边
[]
>>> re.findall(s$,s)
[s]
>>> re.findall(.s$,s)
[gs]

# *表示匹配前面字符0到多次,用在字符之后,只针对前面的一个字符
>>> s = "aabbccddabcdabcd"
>>> re.findall(a*,s)    #匹配0到多次,所以会打印没有匹配到的
[aa, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, ‘‘, a, ‘‘, ‘‘, ‘‘, a, ‘‘, ‘‘, ‘‘, ‘‘]
>>> re.findall(aa*,s)      #匹配第二个a出现的0到多次
[aa, a, a]
>>> re.findall(ab*,s)    #匹配b出现的0到多次
[a, abb, ab, ab]


# + 匹配前面的字符1到多次,最少有一个
>>> re.findall(a+,s)      #最少出现一个a
[aa, a, a]
>>> re.findall(aa+,s) #最少出现一个aa
[aa]
>>> re.findall(ab+,s)    #最少出现一个ab
[abb, ab, ab]

# ?  匹配前面的字符0-1次,只能出现一次或没有
>>> s = "aa bb cc dd abcd ababcdcd"
>>> re.findall(aa?,s)      
[aa, a, a, a]
>>> re.findall(ab?,s)
[a, a, ab, ab, ab]  #匹配出现一次b或者没有,所结果中b只能出现一次或者没有

# / 转义功能,去除后面字符的特殊意义
>>> s = "* *? +> <>"       
>>> re.findall(^\*,s)   #匹配*号
[*]
>>> re.findall(\*.,s)
[* , *?]

#{} 指定匹配次数
 s = "aa bb aaa bbb aabbcc aaabbb  abab ababab"
>>> re.findall(a{1,2},s)   #匹配a出现的1-2次,即a aa
[aa, aa, a, aa, aa, a, a, a, a, a, a]
>>> re.findall(ab{1,2},s)     #匹配ab或 abb
[abb, abb, ab, ab, ab, ab, ab]

# []   或的作用
>>> s = "abc adc aec adec abbc addc abbbc adddc ac abbddc"
>>> re.findall(a[db]c,s)   #匹配abc 或adc
[abc, adc]
>>> re.findall(a[db]+c,s)   #匹配ac中间至少1个b或d,可以有多个
[abc, adc, abbc, addc, abbbc, adddc, abbddc]
>>> re.findall(a[db]?c,s)   #匹配ac中间一个a或b,可以没有
[abc, adc, ac]
>>> re.findall(a[db]*c,s) #匹配ac中间0到多个b或d
[abc, adc, abbc, addc, abbbc, adddc, ac, abbddc]
>>> re.findall(a[^db]c,s)   #匹配ac中间不出现b或d的情况 ^在这里表示非
[aec]

>>> s = "abc abbbbbc  a1231c  a_+_+_+_+_+_c "  
>>> re.findall(a[a-z,0-9]+c,s)  #匹配ac中间是字母或数字
[abc, abbbbbc, a1231c]

 

  • 其他特殊意义的字符加字母:

    • \w 匹配包括下划线的任何单词字符。等价于‘[A-Za-z0-9_]‘。
    • \W 匹配任何非单词字符。等价于 ‘[A-Za-z0-9_]‘。
    • \s 匹配任意空白字符,等价于 [\t\n\r\f].
    • \S 匹配任意非空字符
    • \d 匹配任意数字,等价于 [0-9].
    • \D 匹配任意非数字
    • \A 匹配字符串开始
    • \Z 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串。c
    • \z 匹配字符串结束
    • \G 匹配最后匹配完成的位置。
    • \b 匹配一个单词边界,也就是指单词和空格间的位置。例如, ‘er\b‘ 可以匹配never 中的 ‘er‘,但不能匹配 verb 中的 ‘er‘。
    • \B 匹配非单词边界。‘er\B‘ 能匹配 verb 中的 ‘er‘,但不能匹配 never 中的 ‘er‘。
    • \n, \t, 等. 匹配一个换行符。匹配一个制表符。等
    • \1...\9 匹配第n个分组的子表达式。
    • \10 匹配第n个分组的子表达式,如果它经匹配。否则指的是八进制字符码的表达式。

    具体实例:

>>> s = "1234 abcd ABCD _ * <>"
>>> re.findall(\\w,s)
[1, 2, 3, 4, a, b, c, d, A, B, C, D, _]
>>> re.findall(\\W,s)
[ ,  ,  ,  , *,  , <, >]
>>> re.findall(\\s,s)
[ ,  ,  ,  ,  ]
>>> re.findall(\\S,s)
[1, 2, 3, 4, a, b, c, d, A, B, C, D, _, *, <, >]
>>> re.findall(\\d,s)
[1, 2, 3, 4]
>>> re.findall(\\D,s)
[ , a, b, c, d,  , A, B, C, D,  , _,  , *,  , <, >]
>>> re.findall(\\A,s)
[‘‘]
>>> re.findall(\\A1,s)
[1]
>>> re.findall(\\A2,s)
[]
>>> re.findall(\\Z\>,s)
[]
>>> re.findall(\>\\Z,s)
[>]

 

PS:
反斜杠的困扰
与大多数编程语言相同,正则表达式里使用"作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配文本中的字符",那么使用编程语言表示的正则表达式里将需要4个反斜杠\\:前两个和后两个分别用于在编程语言里转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,这个例子中的正则表达式可以使用r\表示。同样,匹配一个数字的\d可以写成r\d。有了原生字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。
所谓原生字符串就是python解释器不在解释规则在python中的含义,而是直接交给re模块来处理

  • 分组匹配

分组匹配一般使用(),被括起来的表达式将作为一组,上面所说的只是针对单个字符串,如果需要匹配多个字符串,则用到了分组匹配。先匹配成功全部正则,再匹配成功的局部内容提取出来
如下:

>>> s = "aa bb aaa bbb aabbcc aaabbb  abab ababab"
>>> re.findall((ab).,s)   #同时匹配ab
[ab, ab, ab, ab]

 

下面将在re模块常用函数中来说明

3. 正则匹配方式:

  • re.findall(pattern, string) 匹配字符串中所有符合规则的字符串,并以列表形式返回

注意:
findall如果使用了分组,则输出的内容将是分组中的内容而非find到的结果,
为了得到find到的结果,要加上问号来启用“不捕捉模式”,就可以了。

>>> re.findall("www.(baidu|xinlang)\.com","www.baidu.com")
[baidu]
>>> re.findall("www.(?:baidu|xinlang)\.com","www.baidu.com")
[www.baidu.com]

 

  • re.match(pattern, string, flags=0) 只匹配字符串中开头符合规则的字符串,其返回的是一个对象 pattern 是正则规则 string 是字符串 flags 是匹配模式
>>> s = 123abc4545
>>> re.match(r\w,s)
<_sre.SRE_Match object; span=(0, 1), match=1>
>>> re.match(r\w,s).group()   只匹配字符串开头
1

 

  • re.search(pattern,string,flags=0) 匹配字符串的所有,但是匹配即停止,只返回第一个匹配的字符 pattern 是正则规则 string 是字符串 flags 是匹配模式
>>> s = 123abc4545
>>> re.search(r\w,s)
<_sre.SRE_Match object; span=(0, 1), match=1>
>>> re.search(r\w,s).group()
1
>>> re.search(r\D,s).group()
a

 

  • PS:以上match和search都返回的是对象,其返回的对象有以下属性和方法:

    • 属性:

      • string: 匹配时使用的文本。
      • re: 匹配时使用的Pattern对象。
      • pos: 文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。
      • endpos: 文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。
      • lastindex: 最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None。
      • lastgroup: 最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None。
    • 方法:

      • group([group1, …]): 获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。
      • groups([default]): 以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。
      • groupdict([default]): 返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。
      • start([group]): 返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。
      • end([group]): 返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。
      • span([group]): 返回(start(group), end(group))。
      • expand(template): 将匹配到的分组代入template中然后返回。template中可以使用\id或\g、\g引用分组,但不能使用编号0。\id与\g是等价的;但\10将被认为是第10个分组,如果你想表达\1之后是字符‘0‘,只能使用\g0。

    举例:

>>> a = "123abc456"
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a)
<_sre.SRE_Match object; span=(0, 9), match=123abc456>
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group()
123abc456
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)
123abc456
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)
123
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)
abc
>>> re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)
456

 



# group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 
 列出第三个括号匹配部分。
  • 其他函数

    • split 使用正则分割字符串
    >>> s = "a1b2c3"
    >>> re.split(\d,s)
    [a, b, c, ‘‘]   #注意后面的空字符串,因为最后一个是数字,所以后边就多一个空字符

     

    • sub 替换匹配成功的指定位置字符串
    >>> s = "a1b2c3"
    >>> re.sub(\d,-,s)
    a-b-c-

     

    • compile 将正则表达式编译成Pattern对象,后面可以直接调用
    >>> a = re.compile(\d)
    >>> s = "a1b2c3"
    >>> a.findall(s)
    [1, 2, 3]

     

    • finditer 搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器
>>> a = re.compile(\d)
>>> s = "a1b2c3"
>>>for m in a.finditer(s):print(m.group())
...
1
2
3

 

4.常用正则匹配

  • 匹配手机号
>>> s = "my name is jeck, my phone is 18611112222, my email is [email protected],my ip is 10.20.10.20,,my ID card is 110521199012256515"
>>> re.findall((1[3578]\d{9}),s)
[18611112222]
>>> re.search((1[3578]\d{9}),s).group()
18611112222
>>> re.search((13[0-9]|15[0|1|2|3|5|6|7|8|9]|18[0|1|2|3|5|6|7|8|9])\\d{8},s).group()
18611112222

 

  • 匹配身份证
s = "my name is jeck, my phone is 18611112222, my email is [email protected],my ip is 10.20.10.20,,my ID card is 110521199012256515"
>>> re.search("([1-9]\\d{5}[1-9]\\d{3}((0\\d)|(1[0-2]))(([0|1|2]\\d)|3[0-1])\\d{3}([0-9]|X)$)",s).group()
110521199012256515

 

  • 匹配ip地址
s = "my name is jeck, my phone is 18611112222, my email is [email protected],my ip is 10.20.10.20,,my ID card is 110521199012256515"
>>> re.search(\d+\.\d+\.\d+\.\d+,s).group()
10.20.10.20
>>> re.search(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3},s).group()
10.20.10.20
  • 匹配邮箱
>>>s = "my name is jeck, my phone is 18611112222, my email is [email protected],my ip is 10.20.10.20,,my ID card is 110521199012256515"
>>>re.search(([a-zA-Z0-9._%+-])[email protected]([a-zA-Z0-9.-]+\.[a-zA-Z]{2,4}),s).group()
[email protected]

 

以上是关于正则表达式re模块的主要内容,如果未能解决你的问题,请参考以下文章

第43天python学习re模块学习

常用模块-正则re

python成长之路第三篇_正则表达式

python成长之路第三篇_正则表达式

python知识-正则表达式re模块

正则表达式