python内置模块【re正则表达式】

一大堆文本中提取其中指定的数据,用正则表达式

1.正则表达式原则

  • 正则表达式是为了找到符合某种模式的字符串
  • 模式包括:是什么字符,重复多少次,在什么位置,有哪些额外的约束。

1.1 匹配单个字符与数字

匹配说明
.匹配除换行符以外的任意字符,当flags被设置为re.S时,可以匹配包含换行符以内的所有字符
[]里面是字符集合,匹配[]里任意一个字符
[0123456789]匹配任意一个数字字符
[0-9]匹配任意一个数字字符
[a-z]匹配任意一个小写英文字母字符
[A-Z]匹配任意一个大写英文字母字符
[A-Za-z]匹配任意一个英文字母字符
[A-Za-z0-9]匹配任意一个数字或英文字母字符
[^lucky] []里的^称为脱字符,表示非,匹配不在[]内的任意一个字符
^[lucky] 以[]中内的某一个字符作为开头
\d一个数字字符,相当于[0-9]
\D一个非数字字符,相当于[^0-9]
\w字母、下划线、数字中的任意一个字符,相当于[0-9A-Za-z_]
\W匹配非字母、下划线、数字中的任意一个字符,相当于[^0-9A-Za-z_]
\s匹配空白符(空格、换页、换行、回车、制表),相当于[ \f\n\r\t]
\S匹配非空白符(空格、换页、换行、回车、制表),相当于[^ \f\n\r\t]
  • 注意:大写字母与小写字母匹配的是相反的

1.2 锚字符

  • 判定是否按照规定开始或者结尾
匹配说明
^行首匹配,和[]里的^不是一个意思
$行尾匹配
\A字符串开头,和^的区别是\A只匹配整个字符串的开头,即使在re.M模式下也不会匹配其他行的行首
\Z字符串结尾,和$的区别是\Z只匹配整个字符串的结尾,即使在re.M模式下也不会匹配其他行的行尾
\b单词边界
\B非单词边界
(?=…)匹配…出现在之后的位置
(?!…)匹配…不出现在之后的位置
(?<=…)匹配…出现在之前的位置
(?<!…)匹配…不出现在之前的位置
(?())

1.3 限定符

  • 指定正则表达式的一个给定组件必须要出现多少次才能满足匹配
匹配说明
(xyz)匹配()内的xyz,作为一个整体去匹配 一个单元 子存储,()表示分组,分组后可以以组为单位应用量词
x?匹配0个或者1个x,非贪婪匹配 0-1个
x*匹配0个或任意多个x ,0-多个
x+匹配至少一个x,1-多个
x{n}确定匹配n个x,n是非负数
x{n,}至少匹配n个x
x{n,m}匹配至少n个最多m个x
x|y|表示或的意思,匹配x或y

1.4 修正符

说明
re.I是匹配对大小写不敏感,即忽略大小写
re.M多行匹配,影响到^和$
re.S使.匹配包括换行符在内的所有字符

1.5 python常用re函数

  • 查找

    查找函数说明
    search浏览整个字符串去匹配第一个,未匹配成功返回None ,返回match对象
    match从开头开始匹配,匹配成功返回一个对象,未匹配成功返回None,只返回一个
    findall返回所有匹配的字符串列表
    finditer生成迭代器对象,包含所有的匹配,需要遍历才能得到里面的每一个数据
  • 替换

    函数说明
    sub替换匹配的字符串,返回替换完成的文本
    subn替换匹配的字符串,返回替换完成的文本 和替换的次数
  • 分割

    函数说明
    split根据匹配成功的位置分割 ,即用匹配的字符串做分隔符分割原字符串
  • 分组

    group说明
    .group()返回所有组组成的结果,即返回整体 ,相当于.group(0)
    .groups()以元祖的形式返回所有组数据
    .group(number)返回数据的第几组
  • Match对象相关方法

    <re.Match object; span=(5, 8), match=‘abc’>说明
    data.group()即返回整体结果
    data.span()返回匹配数据的索引范围
    data.start()返回匹配数据的开始索引
    data.end()返回匹配数据的结束索引
    data.string原数据字符串
  • 其他

    函数说明
    compile预加载, 提前把正则对象加载完毕,直接把加载好的正则进行使用
    (?P<名字>正则)想要提取数据必须用小括号括起来. 可以单独起名字, 提取数据的时候. 需要group(“名字”)

1.6 贪婪与非贪婪匹配

  • 贪婪模式
    • 匹配尽可能多的字符
模式说明
.+匹配换行符以外的字符至少一次
.*匹配换行符以外的字符任意次
  • 非贪婪模式
    • 尽可能少的匹配
模式说明
.+?匹配换行符以外的字符至少一次
.*?匹配换行符以外的字符任意次

1.7 分组

  • 分组,把一个正则表达式分成几个部分,这样可以重复某个分组,或者指定两个分组必须相同等额外的要求。
    正则匹配
    (…)捕获一个组
    (?P < Y >…)捕获组名为Y
    (?:…)不捕获组
    (?P =Y)匹配第Y个匹配到的组
    (?#…)注释

2.实例

2.1 字符串相关

2.1.1 文本匹配(查找)

  • 'wxy’匹配文本中的wxy

    import re
    text='你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
    data_list=re.findall('wxy',text)
    print(data_list) #['wxy', 'wxy']
    

2.1.2 [abc]

  • 匹配文本中的a或b或c字符

    import re
    text='你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
    data_list=re.findall('[abc]',text)
    print(data_list) #['a', 'a']
    

2.1.3 [^abc]

  • 匹配处理abc以外的字符

    import re
    text='你好,angle'
    data_list=re.findall('[^abc]',text)
    print(data_list) #['你', '好', ',', 'n', 'g', 'l', 'e']
    

2.1.4 [a-z]

import re
text='你好,angle'
data_list=re.findall('[a-z]',text)
print(data_list) #['a', 'n', 'g', 'l', 'e']

2.1.5 .

import re
text='你好,angle,a\n'
data_list=re.findall('a.',text)
print(data_list)# ['an']

2.1.6 \w

import re
text = '你好,a_n_g_le\n'
data_list = re.findall('\w', text)
print(data_list)  # ['你', '好', 'a', '_', 'n', '_', 'g', '_', 'l', 'e']

2.1.7 \d

import re
text='你好,2698959795用户'
data_list=re.findall('\d',text)
print(data_list) #['2', '6', '9', '8', '9', '5', '9', '7', '9', '5']

2.1.8 \s

import re
text='你好\t,26989用户\n'
data_list=re.findall('\s',text)
print(data_list) #['\t', '\n']

2.2数量相关

2.2.1 *

  • 0-多个

    import re
    text='你好,我叫wxy,你可以叫我wy'
    data_list=re.findall('wx*y',text)
    print(data_list) #['wxy', 'wy']
    

2.2.2 +

  • 1-多个
    import re
    
    text = '你好,我叫wxy,你可以叫我wy,或者wxxxxy'
    data_list = re.findall('wx+y', text)
    print(data_list)  # ['wxy', 'wxxxxy']
    

2.2.3 ?

  • 0-1个
    import re
    text='你好,我叫wxy,你可以叫我wy或wxxxy'
    data_list=re.findall('wx?y',text)
    print(data_list) #['wxy', 'wy']
    

2.2.4 {n}

import re
text='2698959795'
data_list=re.findall('26989\d{5}',text)
print(data_list) #['2698959795']

2.2.5{n,}

import re
text='2698959795'
data_list=re.findall('26989\d{1,}',text)
print(data_list) #['2698959795']

2.2.6 {n,m}

import re
text='2698959795'
data_list=re.findall('26989\d{1,3}',text)
print(data_list) #['26989597']

2.3.括号(分组)

2.3.1 提取数据区域

  • 需要匹配扣扣邮件,查找的时候要根据qq邮件格式查找,但是最终只要qq号,即(qq号)
    import re
    text='2698959795@qq.com'
    data_list=re.findall('(26989\d+)@qq.com',text)
    print(data_list) #['2698959795']
    

2.3.2 获取指定区域+或条件

import re
text='2698959795@qq.com,26989612@qq.com'
data_list=re.findall('((269895\d+|6\d+)@qq.com)',text)
print(data_list) #[('2698959795@qq.com', '2698959795'), ('6989612@qq.com', '6989612')]

2.4.python常用匹配函数

2.4.1 查找

  • findall

    • 返回字符串列表
       import re
       text='你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
       data_list=re.findall('wxy',text)
       print(data_list) #['wxy', 'wxy']
      
  • match

    • 返回match对象
      import re
      text='你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
      data_list=re.match('你好',text)
      print(data_list) #<re.Match object; span=(0, 2), match='你好'>
      print(data_list.group()) #你好
      
    • Match对象相关方法
      import re
      
      text = '你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
      data = re.search(r'wxy', text)
      
      print(data.group())  # wxy
      print(data.span())  # (5, 8)
      print(data.start())  # 5
      print(data.end())  # 8
      print(data.string)  # 你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle
      
  • search

    • 返回match对象
       import re
       text='你好,我叫wxy,英文名为angle,你可以叫我wxy或者angle'
       data_list=re.search('wxy',text)
       print(data_list) #<re.Match object; span=(5, 8), match='wxy'>
       print(data_list.group()) #wxy
      
  • finditer

    • 返回match 对象
      import re
      
      result=re.finditer(r'\d+','我今年18岁, 我有200000000块')
      for item in result:
          #item.group()获取需要的数据
          print(item.group())
      

2.4.2 替换

  • sub

      import re
      
      text = '你好,我叫wxy,你可以叫我wxy或者angle'
      # re.sub(正则表达式包替换的文本,替换成什么,原文本,替换几个)
      data_list = re.sub('wxy', '小红', text)
      data_list1 = re.sub('wxy', '小红', text, 1)
      data_list2 = re.sub(r'(wxy)', r'\1姐姐', text,1)
      print(data_list)  # 你好,我叫小红,你可以叫我小红或者angle
      print(data_list1)  # 你好,我叫小红,你可以叫我wxy或者angle
      print(data_list2)  # 你好,我叫wxy姐姐,你可以叫我wxy或者angle
    
  • subn

    • 返回值:替换后字符串,替换个数
    import re
    text = '你好,我叫wxy,你可以叫我wxy或者angle'
    # re.subn(正则表达式包替换的文本,替换成什么,原文本,替换几个)
    data_list = re.subn('wxy', '小红', text)
    print(data_list)  # ('你好,我叫小红,你可以叫我小红或者angle', 2)
    

2.4.3 分割

  • split
     import re
     text='你好,我叫wxy,你可以叫我wxy或者angle'
     data_list=re.split('wxy',text)
     data_list1=re.split('wxy',text,1)
     print(data_list) #['你好,我叫', ',你可以叫我', '或者angle']
     print(data_list1) #['你好,我叫', ',你可以叫我wxy或者angle']
    

2.4.4 ()分组

  • group

    • group() 同group(0)就是匹配正则表达式整体结果
    • 正则表达式中没有括号,group(1)肯定不对了
    • 正则表达式中的三组括号把匹配结果分成三组
    • group(1) 列出第一个括号匹配部分,group(2) 列出第二个括号匹配部分,group(3) 列出第三个括号匹配部分
    import re
    a = "123abc456"
    res=r"([0-9]*)([a-z]*)([0-9]*)"
    print (re.search(res,a).groups())
    print (re.search(res,a).group())   #123abc456,返回整体
    print (re.search(res,a).group(0))   #123abc456,返回整体
    print (re.search(res,a).group(1))   #123
    print (re.search(res,a).group(2) )  #abc
    print (re.search(res,a).group(3))   #456
    

2.4.5 其他

  • compile

       import re
       text="我今年32岁"
       obj=re.compile(r'\d+')
       result=obj.findall(text)
       print(result)  # ['32']
    
  • (?P<名字>正则)

    obj=re.compile("<span id='(?P<id>\d+)'>(?P<name>.*?)</span>")
    result=obj.finditer(s)
    for item in result:
      id=item.group('id')
      name=item.group('name')
      print(id,name)
    
    • 注意:re.S,可以匹配换行符

3.应用实例

3.1 判断是否为字符

a='我'
punctuation_pattern = r"[^\w\s]"
result=re.findall(punctuation_pattern,a) # 是字符则匹配出来,不是则为空
result

3.2 判断是否无中文

a='我'
pattern = re.compile(r'[\u4e00-\u9fff]+') # 匹配中文
result=re.search(pattern, a) # 无中文,则为空
result

3.3 去除字符串前后标点符号

  • 去除英文标点符号
    a=",我.. "
    result=a.strip().strip(string.punctuation)
    result
    
  • 去除中文和英文标点符号
    string="????你好,Hello,世界....."
    pattern = r'^[^\w\s]+|[^\w\s]+$'
    result = re.sub(pattern, '', string)
    result
    

4. 其他案例

题目来源:麦叔编程

4.1.固定的字符串

  • 要求:确定字符串中是否有123456
    import re
    text = '麦叔身高:178,体重:168,学号:123456,密码:9527,班级:123456'
    print(re.findall(r'123456', text))
    
    在这里插入图片描述

4.2. 某一类单个字符

  • 要求:找出所有的单个的数字
    import re
    text = '体重:168,学号:123456'
    print(re.findall(r'\d', text))
    
    在这里插入图片描述

4.3. 重复某一类字符

  • 要求:找所有的数字,比如178,168,123456,9527等
    import re
    text = '身高:178,体重:168,学号:123456,密码:9527'
    print(re.findall(r'\d+', text))
    

在这里插入图片描述

4.4. 组合查找

  • 要求:找出座机号码
    import re
    text = '电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
    print(re.findall(r'\d{4}-\d{8}', text))
    

在这里插入图片描述

4.5. 多种情况

  • 要求:找出手机号码或者座机号码
    import re
    # |为或,1表示手机号开头第一位为1
    text = '电话是18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
    print(re.findall(r'\d{4}-\d{8}|1\d{10}', text))
    

在这里插入图片描述

4.6.限定位置

  • 要求:在句子开头的手机号码,或座机
    import re
    # ^开头字符
    text = '18812345678,他还有一个电话号码是18887654321,他爱好的数字是01234567891,他的座机是:0571-52152166'
    print(re.findall(r'^1\d{10}|^\d{4}-\d{8}', text))
    
    在这里插入图片描述

4.7.内部约束

  • 要求:找出形如barbar, dardar的前后三个字母重复的字符串
    import re
    
    # \w{3}表示3个字符,放在小括号中(\w{3})就成为一个分组
    # \1表示第一个括号,其中的1就表示第1个括号
    # (\1)表示它里面的内容和第1个括号里的内容必须相同,也就是说3个字符要重复出现两次。
    text = 'barbar carcar harhel'
    print(re.findall(r'(\w{3})(\1)', text))
    
    在这里插入图片描述

4.8 常见例子

  • 匹配Email地址的正则表达式
    res = '\w+([-+.]\w+)*@\w+([-.]\w+)*.\w+([-.]\w+)*'
    
  • 匹配网址URL的正则表达式
    res = '[a-zA-z]+://[^s]*'
    
  • 匹配帐号是否合法(字母开头,允许5-16字母,允许字母数字下划线):
    res = '^[a-zA-Z][a-zA-Z0-9_]{4,15}$'
    
  • 匹配国内电话号码,格式为:区号-号码-分机号,分机号可能没有
    res = 'd{3,4}-d{7,8}-d{3,4}|d{3,4}-d{7,8}'
    
  • 匹配腾讯qq号
    res = '[1-9][0-9]{4,}'
    
  • 匹配中国邮政编码(6位数字)
    res = '[1-9]\d{5}(?!\d)'
    
  • 匹配身份证(15位或18位)
    res = '\d{15}|\d{18}'
    
  • 匹配ip地址
    res = '\d+.\d+.\d+.\d+'
    
  • 形如"carcar"或"barbar"等会重复的三个字符的单词
    res = '(\w{3})(\1)'
    
  • 获取以"密码:"开头的数字
    res = '(?<=密码.)\d+'
    
评论 9
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

荼靡~

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值