python基础-第五篇-5.4正则表达式

Posted 财经知识狂魔

tags:

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

正则基础知识

  • 正则表达式是通过调用re模块实现的
  • 在python里,正则表达式处理对象为字符串,所以正则里方法和字符串的方法有很多相似的地方:re.findall和find,re.split和split,re.sub和replace
  • 普通字符和元字符

  普通字符

    大多数的字符和字母都为普通字符

  元字符

    在正则里,有其特殊的功能的字符称为元字符,如:. ^ $ * + ? {} | () \\

  •  .    除了换行符任意一个字符进行匹配
import re

strs = \'ji154\\n651jia*-\'
m = re.findall(\'.\',strs)  #findall把所有匹配成功的对象装一个列表返回
print(m)
#结果为:[\'j\', \'i\', \'1\', \'5\', \'4\', \'6\', \'5\', \'1\', \'j\', \'i\', \'a\', \'*\', \'-\']
  •   ^  以什么开头
import re
strs = \'alex123\'
m = re.search(\'^alex\',strs)  #匹配成功返回match对象,否则返回None
if m:
    print(m.group()) #alex
  •   $  以什么结尾
import re

strs = \'123alex\'
m = re.search(\'alex$\',strs)
if m:
    print(m.group())  #alex
  •   *  匹配0或多个,贪婪匹配的字符
import re

str1 = \'alexxxxx\'
str2 = \'alex\'
str3 = \'ale\'
m1 = re.match(\'alex*\',str1)  #match从头匹配,匹配成功返回match对象,否则返回None
if m1:
    print(m1.group())  #alexxxxx
m2 = re.match(\'alex*\',str2)
if m2:
    print(m2.group())  #alex
m3 = re.match(\'alex*\',str3)
if m3:
    print(m3.group())  #ale
  •   +  匹配一个或多个,也是贪婪匹配
import re

str1 = \'alexxxxx\'
str2 = \'alex\'
str3 = \'ale\'
m1 = re.match(\'alex+\',str1) 
if m1:
    print(m1.group())  #alexxxxx
m2 = re.match(\'alex+\',str2)
if m2:
    print(m2.group())  #alex
m3 = re.match(\'alex+\',str3)
if m3:  #条件不成立
    print(m3.group())  
print(m3)  #None
  •   ?  匹配0或1个
import re

str1 = \'alexxxx\'
str2 = \'alex\'
str3 = \'ale\'
m1 = re.match(\'alex?\',str1)
if m1:
    print(m1.group())  #alex
m2 = re.match(\'alex?\',str2)
if m2:
    print(m2.group())  #alex
m3 = re.match(\'alex?\',str3)
if m3:
    print(m3.group())  #ale 
  •   {}  规定匹配的个数或范围,范围是开区间,也就是说能取到上界
import re

str1 = \'alexxx\'
str2 = \'alexxxxx\'
m1 = re.search(\'alex{3}\',str1)
if m1:
    print(m1.group())  #alexxx
m2 = re.search(\'alex{3,5}\',str1)
if m2:
    print(m2.group())  #alexxx
m3 = re.search(\'alex{3,5}\',str2)
if m3:
    print(m3.group())  #alexxxxx
  •   []   字符集,匹配过程中字符集的字符是或的关系,而且一个集就匹配一个字符
import re

str1 = \'jing264-*4*df\'
m1 = re.search(\'[a-z]\',str1)  #search从左往右匹配,匹配成功就不再往后匹配
if m1:
    print(m1.group()) #j
m2 = re.findall(\'[a-z]\',str1)
print(m2)    #[\'j\', \'i\', \'n\', \'g\', \'d\', \'f\']

     元字符在字符集中会失去其特有功能,回归本性,除-,^,\\

import re
m = re.findall(\'[^1-9]\',\'ww32sd8l\')  #在字符集里,^表示非,在这里就是非数字
print(m)  #[\'w\', \'w\', \'s\', \'d\', \'l\']
import re
m = re.findall(\'[*\\^]\',\'kdf*nd15^1j5\') #匹配星号或折号
print(m) #[\'*\', \'^\']
  •   ()   组,如同在算式中小括号,具有优先权
import re
m = re.findall(\'(ab)+\',\'abababab156712\')  #findall对组有优先获取权
print(m)  #[\'ab\']
m2 = re.search(\'(ab)+\',\'abababab156712\')
if m2:
    print(m2.group())  #abababab
  •   |  或
import re
m = re.findall(\'(abc)|(1)|(\\n)\',\'jicabc21\\n1\')
print(m)    #[(\'abc\', \'\', \'\'), (\'\', \'1\', \'\'), (\'\', \'\', \'\\n\'), (\'\', \'1\', \'\')]

m = re.findall(\'(\\d)+\',\'abcabc21ji\')
print(m)   #[\'1\']

m = re.findall(\'(abc)\',\'jicabc21\\n1\',re.M)
print(m)  #[\'abc\']

  \\   反斜杠后边跟元字符去除特殊功能:

        正则的\\与python里的\\--当正则规则与python规则相冲突时

#匹配字符里的\\

import re
m = re.findall(\'\\\\\\\\\',\'abc\\com\')
print(m)  #[\'\\\\\']
m2 = re.findall(r\'\\\\\',\'abc\\com\')
print(m2)  #[\'\\\\\']

   

  

  你会不会觉得就因为正则规则和python规则相冲突而把这个搞得好麻烦呢??所以r登场了,它是让python别胡乱瞎搞的

  反斜杠后跟普通字符实现特殊功能

  1. \\d  数字--相当[0-9]
  2. \\D  非数字--相当[^0-9]
  3. \\w   匹配任何字母数字字符--相当[a-zA-Z0-9]
  4. \\W 匹配任何非字母数字字符--相当[^a-zA-Z0-9]
  5. \\s  匹配任何空白字符--相当[ \\t\\n\\r\\f\\v]
  6. \\S 匹配任何非空白字符--相当[^ \\t\\n\\r\\f\\v]
  7. \\b 匹配一个单词边界,也就是单词和空格间的位置(特殊字符也适用)
import re
str1 = \'4d4g2c\\n 5\\v\'
m1 = re.findall(\'\\d\',str1)
print(m1)   #[\'4\', \'4\', \'2\', \'5\']
m2 = re.findall(\'\\w\',str1)
print(m2)  #[\'4\', \'d\', \'4\', \'g\', \'2\', \'c\', \'5\']
m3 = re.findall(\'\\s\',str1)
print(m3)  #[\'\\n\', \' \', \'\\x0b\']

 

import re
str1 = \'alex*eric eva\'
m4 = re.findall(r\'\\b\',str1)
print(m4)  #[\'\', \'\', \'\', \'\', \'\', \'\']

  引用序号对应的字符组所匹配的字符串

import re

m = re.search(r\'(alex)(eric)com\\2\\1\',\'alexericcomericalex\')
if m:
    print(m.group())  #alexericcomericalex

   非贪婪模式化

import re

m1 = re.search(\'a(\\d+?)\',\'a21471\')
if m1:
    print(m1.group())  #a2
m2 = re.search(\'a(\\d*?)\',\'a21471\')
if m2:
    print(m2.group())  #a
#如果前后有限定条件,再加非贪婪?--无效
m3 = re.search(\'a(\\d+?)b\',\'a265532b\')
if m3:
    print(m3.group())  #a265532b
m4 = re.search(\'a(\\d+)b\',\'a265532b\')
if m4:
    print(m4.group())  #a265532b

 

正则常见方法

  • re.match 从头匹配,一旦匹配成功,返回一个match对象

import re
#无分组
origin = \'hello alex bcd alex lge alex ccd 16\'
r = re.match(\'h\\w+\',origin)
print(r.group())   #hello
print(r.groups())  #()--获取模型中匹配到的分组结果--等同于对匹配到的结果再次进行筛选
print(r.groupdict())  #{}--获取模型中匹配到的分组中所有执行了key的组
#有分组
r = re.match(\'(?P<n1>h)(\\w+)\',origin)  #key对应的?P   大写p
print(r.group())   #hello
print(r.groups())  #(\'h\', \'ello\')--获取模型中匹配到的分组结果--等同于对匹配到的结果再次进行筛选
print(r.groupdict())  #{\'n1\': \'h\'}--获取模型中匹配到的分组中所有执行了key的组
  • 而对象有自己的group等方法

  1. group  返回被re匹配的的字符串,参数0或不写--默认匹配所有,1--匹配1组,2--匹配2组,3--匹配3组
  2. start    返回匹配开始的位置
  3. end     返回匹配结束的位置
  4. span    返回一个元组包含(开始,结束)的位置
import re

m1 = re.match(\'(a)(l)(e)(x)\',\'alex\')
print(m1.group(0))  #alex
print(m1.group(1))  #a
print(m1.group(4))  #x
print(m1.start())   #0
print(m1.end())     #4
print(m1.span())    #(0, 4)
  •  第三参数--标志位(match和search差不多)

  1. re.I  使匹配对大小写不敏感
  2. re.S 使.匹配包括换行符在内的所有字符
  3. re.M 支持匹配多行
import re

# m1 = re.search(\'alex\',\'ALEX\',re.I)
# print(m1.group())
# m2 = re.findall(\'.\',\'1d5\\n2d\',re.S)
# print(m2)
str1 = \'123alex\\nalex154ip\\nalex15ip\'
m3 = re.findall(\'^alex\',str1,re.M)
print(m3)  #以行头为头,以行尾为尾,进行^和$匹配
  •  re.findall  匹配所有符合匹配模式的字符,以列表返回,如果遇组,优先捕获组的内容

  • re.finditer  匹配所有符合匹配模式的字符,返回迭代器

import re
n = re.findall(\'\\d+\\w\\d+\',\'a2b3c4d5\')
print(n)  #[\'2b3\', \'4d5\']--你可能会想:怎么没有‘3c4’
#因为是顺序匹配,在没匹配成功的前提下,逐个往后找,所以结果里没有‘3c4’
#一旦匹配成功,等同拿走匹配到的字符串在往下匹配

 

import re

origin = \'hello alex bcd\'
r = re.findall(\'(a)(\\w+)(x)\',origin)
print(r)  #[(\'a\', \'le\', \'x\')]
r2 = re.findall(\'(a)(\\w+(e))(?P<n1>x)\',origin)
print(r2)  #[(\'a\', \'le\', \'e\', \'x\')]  #findall方法里加key是无意义的,因为返回对象是列表,没有groupdict方法

 

import re
m1 = re.findall(\'a(le)x\',\'alexjijfalexjijhfalex\')
print(m1)  #[\'le\', \'le\', \'le\']
#破了findall的优先捕获组的权限--?:
m2 = re.findall(\'www.(?:baidu|laonanhai).com\',\'jfswww.laonanhai.com\')
print(m2)  #[\'www.laonanhai.com\']

 

import re

origin = \'hello alex bcd\'
r = re.finditer(\'(a)(\\w+)(e)(?P<n1>x)\',origin)
print(r)   #match对象组成的迭代器
for i in r:
    print(i)   #<_sre.SRE_Match object; span=(6, 10), match=\'alex\'>
    print(i.group())  #alex
    print(i.groups()) #(\'a\', \'l\', \'e\', \'x\')
    print(i.groupdict()) #{\'n1\': \'x\'}

 

import re

a = \'alex\'
n = re.findall(\'(\\w)(\\w)(\\w)(\\w)\',a)
print(n)  #[(\'a\', \'l\', \'e\', \'x\')]
n2 = re.findall(\'(\\w){4}\',a)
print(n2)  #[\'x\']
n3 = re.findall(\'(\\w)*\',a)
print(n3)  #[\'x\', \'\']    *最后会匹配一次空

 

import re
p = re.compile(r\'\\d+\')
w = p.finditer(\'12 drwn44ers drumming,11alex10eric\')
print(w)
for mat in w:
    print(mat.group(),mat.span())
结果为:
        <callable_iterator object at 0x0000000000D1FC50>
        12 (0, 2)
        44 (7, 9)
        11 (22, 24)
        10 (28, 30)
  • re.search 逐个往后找,匹配到一个,不再匹配,匹配成功返回一个match对象,没有匹配到就返回None

import re

m = re.search(\'alex\',\'abalexsalex\')
print(m)
if m:
    print(m.group())  #alex
  • re.sub(’匹配模式‘,’新的‘,’旧的‘,’次数‘)

  • re.subn--自动计算替换次数

import re

m = re.sub(\'\\d\',\'love\',\'i1you2you\',1)
print(m)  #iloveyou2you

m2 = re.subn(\'\\d\',\'love\',\'1df4d17g4d8t12df\')
print(m2)  #(\'lovedflovedloveloveglovedlovetlovelovedf\', 8)
  •  re.compile  把正则表达式编译成一个正则表达式对象,当要对同一个正则规则使用多次时,建议用这种方式

import re
regex = re.compile(r\'\\w*oo\\w*\')
print(regex.findall(\'jisf4oo12df14\'))  #[\'jisf4oo12df14\']
  •  re.split  以匹配模式匹配到的字符串一个一个分割,如果匹配模式里有组,还会返回匹配上组的内容,第三参数为分割次数

import re
m = re.split(\'alex\',\'jifalex15jialexdf7\')
print(m)  #[\'jif\', \'15ji\', \'df7\']

m = re.split(\'(alex)\',\'jifalex15jialexdf7\')
print(m)  #[\'jif\', \'alex\', \'15ji\', \'alex\', \'df7\']

 

                                                欢迎大家对我的博客内容提出质疑和提问!谢谢

                                                                             笔者:拍省先生  

以上是关于python基础-第五篇-5.4正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

Python学习笔记——基础篇第五周——正则表达式

Python基础

第五篇:python基础_5

Python零基础入门

python学习第五篇 常用模块

Python基础