正则表达式常用方法

正则切割

import re
c =re.compile(r'\d')
s='hello52bthg235gfre'
ret=c.split(s,count=2)
print(ret)

正则替换

import re

r='sd7fB2dv2B1cfB;'
d=re.sub('\d','&',r,count=2)
print(d)#替换,及指定替换次数,不指定就全部替换

s = "1abc23def45"
#用?将s中符合r"\w"匹配的替换,打印替换后的结果及替换个数在一个元组内。
print(str(re.subn(r"\w", "?", s)[1]))#可以在中括号内输入下标选择打印


#替换
c =re.compile(r'\d')
s='hello52bthg235gfre'
ret=c.sub('&',s,count=2)
print(ret)
#封装调用函数人为干预替换过程
def double(s):
    print(s)
    return str(int(s.group())*2)
##先用正则公式对字符串进行匹配,匹配到后对应给要替换的位置参数,一看是函数把正则结果返回到函数进行处理获取返回值进行替换
d=re.sub(r'\d', double, 'dg2hfgh4fh')

应用场景

  • 特定规律字符串的查找切割替换等
  • 邮箱格式、URL、IP等的校验
  • 爬虫项目中,特定内容的提取

使用原则

  • 只要使用字符串等函数解决的问题,就不要使用正则
  • 正则的效率比较低,同时会降低代码的可读性。
  • 世界上最难理解的三样东西:医生的处方、道士的神符、码农的正则。
  • 提醒:正则是用来写的,不是用来读的;在不指定功能的情况下,不要试图阅读别人的正则。

基本使用match/search/findall/compile

  • 说明:正则不是我们写的,python中正则的解析通过re模块完成
  • 相关函数:
    • match:从开头进行匹配,匹配到就返回正则结果对象,没有返回None。

    • search:从任意位置匹配,功能同上。
      #从开头查找,找到返回正则匹配结果对象,没有找到返回None
      #m = re.match(‘abc’, ‘abcdask;jabcsdajl’)
      #从任意位置查找,功能同上
      m = re.search(‘abc’, ‘shdalsjdabchaoeor’)

      if m:
      # 返回匹配的内容
      print(m.group())
      # 返回匹配内容位置
      print(m.span())

    • findall:全部匹配,返回匹配到的内容组成的列表,没有返回空列表。
      #先生成正则表达式对象
      c =re.compile(‘hello’)
      #从开头匹配
      x =c.match(‘scdvdshello;csd55’)
      #从任意位置查找
      z =c.search(‘scdvdshello;csd55’)
      #返回所有匹配内容的列表,若没找到返回空列表
      #f =c.findall(‘scdvdshello;csd55’)
      f =re.findall(‘ab’,‘scabvdshelablo;csabd55’)
      #与上边等同
      f =re.findall(’(ab)’,‘scdvabdshabello;csabd5’)
      #按照正则公式整体查找但是只打印括号内的,有多个括号时匹配到打印各个括号内的内容到一个元组内
      f =re.findall(‘sd(ab)hn’,‘ssdabhnllsdabhn5’)
      [‘ab’, ‘ab’]
      f =re.findall(‘sd(ab)h(ab)n’,‘ssdabhabn5’)
      [(‘ab’, ‘ab’)]
      #先按照最外边括号匹配找到打印括号内内容,再去掉外边括号再次匹配打印
      f =re.findall(’(sd(ab)h(ab)n)’,‘ssdabhabn5sdabhabn’)
      [(‘sdabhabn’, ‘ab’, ‘ab’), (‘sdabhabn’, ‘ab’, ‘ab’)]
      #按照括号里的或语法依次匹配打印
      f =re.findall(‘a(hello|world)c’,‘sahellochg25aworldcn’)
      [‘hello’, ‘world’]
      #先匹配外部括号再去掉外部括号再次匹配分别打印到元组
      f =re.findall(’(a(hello|world)c)’,‘sahellochg25aworldcn’)
      [(‘ahelloc’, ‘hello’), (‘aworldc’, ‘world’)]
      print(f)

      #匹配所有内容,找到返回所有匹配的内容列表,没有找到返回空列表
      f = re.findall(‘abcd’, ‘adsjkjdabcajsdlasabcjsdlaabc’)
      print(f)

    • compile:生成正则表达式对象
      #先生成正则表达式对象
      c = re.compile(‘hello’)
      #print(type©)

      #从开头匹配
      m = c.match(‘hellosadk;ask;kahellosadhlkas’)
      print(m)

      #从任意位置匹配
      s = c.search(‘hadlsjasdhellokjsdlks’)
      print(s)

      #匹配所有内容
      f = c.findall(‘hellosdhasdjahelloshdajldhello’)
      print(f)
      说明:此方式更加灵活,将正则匹配分为两步完成(先生成正则对象,然后需要时进行匹配)

正则规则

单个字符\d \B [ ]

普通字符:简单来说就是一对一的完全匹配。
[]:中间的任意一个字符
	[a-z]:a~z之间的任意字符(所有的小写字母)
	[a-zA-Z]:匹配所有的字母,多个连续的片段中间不能有任何多余的字符
	[^0-9]:匹配除0-9以外的任意字符
. :匹配除'\n'以外的任意字符
\d:数字字符,等价于[0-9]
\D:非数字字符,等价于[^0-9]
\w:匹配字(数字、字母、下划线、汉字)
\W:匹配非字(\w相反的内容)
\s:所有的空白字符(\n、\t、\r、空格)
\S:非空白字符(\s相反的内容)
\b:词边界(开头、结尾、空格、标点等)
\B:非词边界(\b相反的内容)

次数限定+ ? {m,n}

*:前面的字符出现任意次
+:至少一次
?:最多一次
{m,n}:m <= 次数 <= n
{m,}:至少m次
{,n}:至多n次
{m}:指定m次

边界限定:^ $

  • ^:以指定的内容开头

  • $:以指定的内容结束

  • 示例:

    import re

    #^:以指定内容开头
    #f = re.findall(’^hello’, ‘hellosjdhelloalskdhello’)

    #$以指定内容结尾
    f = re.findall(‘hello$’, ‘hellosjdhelloalskdhello’)

    print(f)

优先级控制:’|’

  • |:表示或,它拥有最低的优先级

  • ():表示一个整体,可以明确的指定结合性/优先级

  • 示例:

    import re

    f = re.findall(‘a(hello|world)c’, ‘sahdjsahellocaworldcjsdhs’)

    print(f)

分组匹配:\1

  • 示例1:

    import re

    c = re.compile(r’(\d+)([a-z]+)(\d+)’)

    s = c.search(‘sdsdj235sadhasjd36432sjdha’)

    #完整匹配结果
    print(s.group(), s.span())
    #等价于上式
    print(s.group(0), s.span(0))
    #第几个()匹配的结果
    print(s.group(1), s.span(1))
    print(s.group(2), s.span(2))
    print(s.group(3), s.span(3))

  • 示例2:

    import re

    #固定匹配
    #c = re.compile(r’\w+’)

    #\1表示前面第一个()匹配的内容
    #c = re.compile(r’<([a-z]+)><([a-z]+)>\w+’)

    #给分组()起名字
    c = re.compile(r’<(?P[a-z]+)><(?P[a-z]+)>\w+’)

    s = c.search(’

    ’)

    if s:
    print(s.group())

贪婪匹配

  • 贪婪:最大限度的匹配。正则的匹配默认就是贪婪的。

  • 非贪婪:只要满足条件,能少匹配就少匹配。’?'经常用于取消贪婪

  • 示例:

    import re
    
    # ?:取消任意多次的贪婪匹配
    # c = re.compile(r'a.*?b')#可以没有,从左侧开始符合就返回尽可能的少匹配
    
    # ?:取消至少一次的贪婪匹配
    c = re.compile(r'a.+?b')#至少要有一个,从左侧开始符合就返回尽可能的少匹配
    
    s = c.search('ssjdsdabjdsd')
    
    if s:
        print(s.group()) 
    

匹配模式re.I忽略大小写/re.M多行匹配/re.S作为单行处理,忽略\n

  • 说明:所谓匹配模式就是对匹配的原则进行整体的修饰。

  • 示例:

    import re

    #忽略大小写re.I
    s = re.search(r’hello’, ‘HELLO world’, re.I)

    #正则默认是单行匹配,使用 re.M 可以进行多行匹配
    s = re.search(r’^hello’, ‘sdhasdh\nhello world’, re.M)

    #使.匹配任意字符,作为单行处理,忽略\n
    #string = ‘

    hello

    string = ‘’’

    hello
    ’’’
    s = re.search(r’
    .*?
    ’, string, re.S)

    if s:
    print(s.group())

    import re

    m=re.match(‘abc’,‘vvvcxdabc52ff2d…’)#只从开头查找
    print(m)
    n=re.search(‘abc’,‘vvvcxdabc52ff2d…’)#从任意位置查找
    print(n)

    if m:
    print(m.group())#打印匹配内容
    print(m.span())#打印匹配内容位置

    f = re.findall(‘abc’,‘5abc1cdfdabc2abc15f.;’)
    print(f)#返回所有匹配内容的列表,若没找到返回空列表

    #先生成正则表达式对象
    c =re.compile(‘hello’)

    #从开头匹配
    x =c.match(‘scdvdshello;csd55’)
    #从任意位置查找
    z =c.search(‘scdvdshello;csd55’)
    #返回所有匹配内容的列表,若没找到返回空列表
    f =c.findall(‘scdvdshello;csd55’)

    #单个字符
    #匹配连续字符,[]中间的任意一个字符
    #[a-z]:a~z之间的任意一个字母
    c=re.compile(’[sdc]’)
    d=re.compile(’[a-z]’)
    #匹配所有的字母,多个连续的片段中间
    #不能有任何多余的字符
    e=re.compile(’[a-zA-Z]’)
    #匹配相反的字符(除指定的字符以外的)
    #加上个’^‘箭头
    g=re.compile(’[^fas]’)
    #’.‘匹配出’\n’以外的任意字符
    o=re.compile(’.’)

    #\d只匹配0~9的数字
    k=re.compile(’\d’)
    #\D匹配除数字以外的字符

    #\w匹配字(数字,字母,下划线,汉字)

    #\W非字以外的字符

    #\s所有的空白字符(\n,\t,\r空格)
    j=re.compile(’\s’)
    v=c.findall(‘scfvsa sfv\ndcs’)
    #\S非空白字符

    #\b词边界\b在python中有特殊意义需要加r
    l=re.compile(r’\bhello’)
    n=c.findall(‘helloscfvs,helloavdcshello’)
    #\B非词边界

    #用控制字符可以出现任意次
    h=re.findall('ab
    c’,‘savdfdbbabbcbbabcbbfvwe’)
    #要求某字符至少出现一次
    m=re.findall(‘ab+c’,‘savdfdbbabbcbbabcbbfvwe’)
    #要求至多一次
    q=re.findall(‘ab?c’,‘savdfdbbabbcbbabcbbfvse’)
    #指定出现次数
    p=re.findall(‘ab{3}c’,‘savdfdbbabbcbbabcbbfse’)
    #指定出现次数的范围,包括边界[1,3]
    r=re.findall(‘ab{1,3}c’,‘sdavdfdbbabfvswe’)
    #指定至多多少次
    s=re.findall(‘ab{0,3}c’,‘sdavdfdbbabbbcbswe’)
    #指定至少多少次
    t=re.findall(‘ab{3,}c’,‘sdavdfdbbabbbcbbbfvswe’)

    #边界限定
    #以指定内容开头
    t=re.findall(’^hello’,‘hellosdafdbhellobfvswe’)
    #以指定内容结尾
    u=re.findall(‘hello$’,‘hellosdafdbhellobhello’)

    #优先级控制
    #指定内容有多个时,’|'它拥有最低优先级出现hello或world或两个都有都可以
    w=re.findall(‘hello|world’,‘hellosdafdbhworldellllo’)
    #a和c之间出现hello或world,只能有两个中的一个
    y=re.findall(‘a(hello|world)c’,‘hellosdafdbhworldellllo’)
    print(w)

    #分组匹配

    #固定匹配:\1代表前边第一个括号内的内容
    j=re.compile(r’<([a-z]+)>\w+’)
    s=j.search(’百度’)

    j=re.compile(r’<([a-z]+)><([a-z]+)>\w+’)
    s=j.search(’

    ’)

    #给分组()起名字
    j=re.compile(r’<(?P[a-z]+)><([a-z]+)>\w+’)
    s=j.search(’

    ’)

    #贪婪匹配
    n=re.compile(r’a.b’)
    m=n.search(‘cdfadfdacvbdvd’) #尽可能多的匹配
    print(m)
    #非贪婪
    #’?'取消任意次数贪婪匹配
    n=re.compile(r’a.
    ?b’)
    m=n.search(‘cdfadfdacvbdvd’) #尽可能少的匹配
    print(m)

    #’?‘取消至少一次的贪婪匹配
    n=re.compile(r’a.+?b’)
    m=n.search(‘cdfadfdacvbdvd’) #尽可能少的匹配
    print(m)

    #忽略大小写re.I
    n=re.compile(r’hello’,‘hello world’,re.I)
    #正则是默认单行匹配,使用re.M可以进行多行匹配
    n=re.compile(r’hello’,‘hello\nworld’,re.M)

    #使’.‘匹配任意字符,re.s作为单行处理,忽略\n
    string=’

    hello

    n=re.compile(r’’)

你可能感兴趣的:(正则表达式)