栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Python实践:Python文本处理之正则表达式

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Python实践:Python文本处理之正则表达式

Python实践:Python文本处理之正则表达式

文章目录
  • Python实践:Python文本处理之正则表达式
    • 初级三板斧
    • 进阶登堂入室
    • Python实战
      • 分割
      • 分组
    • 隋唐练习
    • 参考资料

正则表达式是一种用来匹配字符串的强有力的武器,利用 字符来匹配字符的思想,基于显示规则进行模式匹配,可以高效组合成不同样式的字符串,迅速处理字符串。

相信我,学会正则表达式,你在以后的文本处理时,一定会感谢我。温馨提示,建议配合《廖雪峰的Python正则表达式教程》研读,见文末参考资料1。

初级三板斧

基础元字符意义总结如下,日常情况都是以下举例的组合:

  • d,表示一个数字

  • w,表示一个字母或数字

  • . , 表示任意一个字符,如:'py.‘可以匹配’pyc’、‘pyo’、'py!'等

  • *, 表示任意个字符(包括0个),对前一个字符模式重复任意次

  • +, 表示至少一个字符

  • ?, 表示0个或1个字符

  • {}, 表示自定义个字符个数,修饰前面一个变量最长的字符个数,如{n}表示n个字符;{n,m}表示n-m个字符,可取到m个字符

  • s, 表示一个空白符,如空格Space、Tab等,s+可表示至少有一个空格

组合示例:

  • d{3,8} ,表示3-8个数字组成的字符串,例如’123’或’12345678’
  • d{3},表示3个数字,例如’010’
  • w.,表示任意一个字符(字符或数字)配一个任意字符, 如’a.', ‘p!’
  • ``s+`,表示至少有一个空白符,如’ ', ’ ’
进阶登堂入室

高频问题总结如下:

  • 转义问题,标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。

    • 如:'-_?.',都是特殊字符,在正则表达式中,要用转义
    • 如:r'py.',才能查找py.这样的字符串
  • |,选择分支表示或的关系,A|B可以匹配A或B,如(P|p)ython可以匹配’Python’或者’python’。

  • [],表示当前一个字符的范围,大于两种的可能;如:[a-zA-Z_][0-9a-zA-Z_]{0, 19},前面1个字符+后面最多19个字符

  • ^,表示行的开头,如^d,表示必须以数字开头。

  • $,表示行的结束,如d$,表示必须以数字结束。

  • (),分组功能,(xyz) 字符组,按照确切的顺序匹配字符 xyz。

  • [^],否定字符类。匹配方括号中不包含的任意字符

组合示例:

  • ^(P|p)y,表示首行以P或p开头,第二个字符为y的字符串
  • ^py&,表示整行匹配,行首以p开头,且中间无字符,行尾以y结束
  • [^w]+ ,表示所有非字母或数字的字符串
Python实战

Python用re模块来使用正则表达式功能,原因是正则表达式的英文为“Regular Expression”,常见缩写为:regex 或 regexp。

import re # 导入正则表达式模块

由于Python的字符串本身也用转义,所以一般使用时要对本身进行转义,变成\。比如:

s = 'ABC\-001' # Python的字符串
# 对应的正则表达式字符串变成:
# 'ABC-001'

但还有个更优雅的解决办法,强烈推荐:

  • 在字符串前加r,表示按字面意思处理,不转义,可达到相同效果
  • 当然,此时n,t,%d等转义字符就无转义功能了
s = r'ABC-001' # Python的字符串
分割

根据re的split()函数,基于正则表达式的Python字符串分割,说明如下:

  • re.split(r'pattern', 'str')
  • 入参1:匹配pattern,入参2:带查找字符串

实例如下:

# 功能:去除空格等空白符,+表示以上形式的字符至少有一个
re.split(r's+', 'a b   c')

# 功能:去除空白符和逗号,+表示以上形式的字符至少有一个
re.split(r'[s,]+', 'a,b, c  d')
分组

主要知识点:

  • groups()函数
  • ()的用法,每个()对应分离出一组结果

再以分离识别时间字符串例子进行说明。

t = '19:05:30'
m = re.match(r'^(0[0-9]|1[0-9]|2[0-3]|[0-9]):(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9]):(0[0-9]|1[0-9]|2[0-9]|3[0-9]|4[0-9]|5[0-9]|[0-9])$', t)
m.groups()  # >>> ('19', '05', '30')

分段理解:

  • (0[0-9]|1[0-9]|2[0-3]|[0-9]),表示识别第一个组,即’19:05:30’中的19
  • 第一组,总体有4种可能形式,用逻辑或|连接
    • 0*
    • 1*
    • 2*
    • *(一位数表示场景)
  • 0[0-9],场景1,表示0字符开头,加一个0-9数字, 00-09
  • 1[0-9],场景2,10-19
  • 2[0-3],场景3,20-23,注意没有24点,因为有00:00
  • [0-9], 场景4,0-9,处理仅一位数的场景

此外,要注意贪心匹配法的问题,以下内容摘自廖雪峰正则表达式文章。

# 默认贪心匹配,即大嘴法,能跟更多的满足条件的组合
>>> re.match(r'^(d+)(0*)$', '102300').groups()
>>> ('102300', '')

# 必须让d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让d+采用非贪婪匹配:
>>> re.match(r'^(d+?)(0*)$', '102300').groups()
>>> ('1023', '00')

行文至此,细心的读者可能发现,一直都是在处理英文字符,如果要查找中文样式的字符如何处理呢?

正则表达式匹配汉字核心思路是:在unicode编码模式下,汉字编码范围:u4e00-u9fa5,可据此进行表征,详细内容见:此文。

隋唐练习

来自廖雪峰文章的作业,根据以上知识试解决以下两个问题。

  • 问题1:一个验证Email地址的正则表达式。如以下Email格式:someone@gmail.com;bill.gates@microsoft.com
  • 问题2:提取出带名字的Email地址。如: tom@voyager.org => Tom Paris;bob@example.com => bob

参考代码及详解如下:

def is_valid_email(addr):
    # [w.]+  表示至少有任意一个字母或者数字或者.出现,多个类似数字依然认可
    # 直到遇到@
    # w+     表示只有字符(字母或数字)出现
    # 直到遇到.com$一直到结尾
    # re_email = re.compile(r'[w.]+@w+.com$') # 将正则表达式预编译,以便经常调用
    # if re_email.match(addr):
    if re.match(r'[w.]+@w+.com$', addr):
        return True
    else:
        return False

def name_of_email(addr):
    # ?', addr)
    return res.group(1) # group是个函数,1是入参,表示分组后的第一个结果,0则表示分组前的内容
参考资料
  1. 廖雪峰正则表达式博客,讲解清晰,简明易懂,入门必备:link
  2. 好心人总结的进阶补充手册,概况全面:link
  3. 菜鸟教程,体系化总结:link
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/861328.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号