• 正则表达式


    正则表达式基础

    1、为什么使用正则

    我这里拿一个例子说明,我们一般做数据处理的时候,会遇到电话号码的情况。
    我们一般的处理方法如下:

    def isPhone(phone):
        # 长度为11
        # 全部都是数字字符
        # 以1开头
        pass
    
    if isPhone("13812345678"):
        print("是手机号")
    else:
        print("不是手机号")
    

    使用正则表达式解决的话

    import re
    
    def isPhone(phone):
        # 正则表达式解释:
        # ^        匹配字符串的开始
        # 1        手机号码以1开头
        # [2-9]    第二位是2到9之间的数字
        # \d{9}    后面跟着9个数字(\d 表示数字,{9} 表示重复9次)
        # $        匹配字符串的结束
        pattern = r'^1[2-9]\d{9}$'
        if re.fullmatch(pattern, phone):
            return True
        else:
            return False
    
    # 测试函数
    if isPhone("13812345678"):
        print("是手机号")
    else:
        print("不是手机号")
    

    这里可以看出正则表达式是一种用于匹配字符串中字符组合的模式,它在文本处理和字符串分析中非常有用。

    2、正则与re模块简介

    则表达式是一种强大的文本处理工具,用于搜索、替换、检查或解析特定模式的字符串。正则表达式使用单个字符串来描述、匹配和处理一系列符合某个句法规则的字符串。

    Python 的 re 模块提供了对正则表达式的全面支持,包括编译正则表达式、执行匹配检查、搜索和替换文本等功能。
    如下四个方法经常使用

    • match()
    • search()
    • findall()
    • finditer()

    正则表达式

    我现在列出一个表格,大家可以看一下常用的匹配模式

    1、匹配单个字符

    在这里插入图片描述

    # []  # 原子表
    [a]
    [ab]  # 匹配a或者b
    [abc]  # 匹配a或者b后者c
    [123]  # 匹配1或者2或者3
    [0-9]  # 匹配任意一位数字
    [a-z]  # 匹配任意以为小写字母
    [A-Z]  # 匹配任意一位大写字母
    [a-zA-Z]  # 匹配任意大小写字母
    
    # [][]
    [abc][0-9]  # 它代表什么意思?  匹配a或者b后者c和任意一位数字  a1
    
    # 匹配手机号码
    1[3-9][0-9]{9}   # {9} 代表前面的[0-9]9位
    
    # ^ 限制开头  $ 限制结尾  一般用于组合
    ^1[3-9][0-9]{9}$  # 完全匹配  匹配的字符串中 必须完全符合才算匹配成功
    15611833906  # 符合
    156118339067  # 不符合
    
    # {} 代表前面正则匹配的n词
    [a-z]{2}  # 匹配俩位小写字母
    [a-z][a-z]  # 等同于上方
    
    # {m,n}  m-n之间的
    [a-z]{2,5}  # 匹配2-5个小写字母
    
    # {m,}  # 至少m个
    [a-z]{2,}  # 至少匹配2个小写字母
    
    # ? 可有可无
    -?[1-9]   # 匹配正负1-9
    
    # .  匹配换行符以外的任意字符
    a  x  z
    
    # * 代表前面的0次到多次  {0,}
    
    
    # .* 组合 了解  贪婪模式  匹配换行符以外的任意字符任意次
    
    # .*? 组合 重要!!!!!!   非贪婪模式 匹配换行符以外的任意字符任意次
    
    # +  匹配一次到多次  {1,}
    
    # .+?  非贪婪模式 匹配换行符以外的任意字符至少1次
    
    # |  代表或
    [a-z]|[0-9] # 匹配字母或数字
    
    # ()  # 1.作为一个单元   2.作为子存储
    
    
    
    
    
    
    

    2、匹配锚字符

    在这里插入图片描述

    • ^ 行首锚:
      匹配字符串的开始位置。
    import re
    pattern = re.compile('^hello')
    print(re.search(pattern, "hello world").group())
    
    • $ 行尾锚:
      匹配字符串的结束位置。
    pattern = re.compile('world$')
    print(re.search(pattern, "Hello world").group())
    
    
    • \A 字符串开始锚:
      匹配字符串的绝对开始位置,与 ^ 类似,但不受多行匹配的影响。
    text = "Hello\nWorld"
    pattern = re.compile(r'\AHello')
    # 这里会匹配,因为 'Hello' 在字符串的绝对开始位置
    result = pattern.search(text)
    

    3、限定符

    在这里插入图片描述

    import re
    
    # (xyz) 匹配括号内的xyz,作为一个整体去匹配
    pattern_group = re.compile(r'(xyz)')
    result_group = pattern_group.search("The string contains xyz.")
    if result_group:
        print("Group matched:", result_group.group())  # 输出: Group matched: xyz
    
    # x? 匹配0个或者1个x,非贪婪匹配
    pattern_optional = re.compile(r'x?')
    result_optional = pattern_optional.search("hello")
    if result_optional:
        print("Optional matched:", result_optional.group())  # 输出: Optional matched: 
    
    # x* 匹配0个或任意多个x
    pattern = re.compile('h*')
    print(re.search(pattern,"hello world")): 
    
    # x+ 匹配至少一个x
    pattern_plus = re.compile(r'x+')
    result_plus = pattern_plus.search("hello")
    if result_plus:
        print("Plus matched:", result_plus.group())  # 输出: Plus matched: lo
    
    # x{n} 确定匹配n个x,n是非负数
    pattern_fixed = re.compile(r'x{3}')
    result_fixed = pattern_fixed.search("xxxx")
    if result_fixed:
        print("Fixed matched:", result_fixed.group())  # 输出: Fixed matched: xxx
    
    # x{n,} 至少匹配n个x
    pattern_at_least = re.compile(r'x{2,}')
    result_at_least = pattern_at_least.search("xxxx")
    if result_at_least:
        print("At least matched:", result_at_least.group())  # 输出: At least matched: xxxx
    
    # x{n,m} 匹配至少n个最多m个x
    pattern_range = re.compile(r'x{1,3}')
    result_range = pattern_range.search("xxxx")
    if result_range:
        print("Range matched:", result_range.group())  # 输出: Range matched: xxx
    
    # x|y \|表示或的意思,匹配x或y
    pattern_alternative = re.compile(r'x|y')
    result_alternative = pattern_alternative.search("x")
    if result_alternative:
        print("Alternative matched:", result_alternative.group())  # 输出: Alternative matched: x
    

    re模块中常用函数

    1、match()函数

    • 功能
      获取成功返回 匹配的对象

    • 参数

    参数说明
    pattern匹配的正则表达式(一种字符串的模式)
    string要匹配的字符串
    flags标识位,用于控制正则表达式的匹配方式
    import re
    
    res = re.match('\d{2}','123')
    print(res.group())
    print(res.span())
    
    #给当前匹配到的结果起别名
    s = '3G4HFD567'
    re.match("(?P\d+)",s)
    print(x.group(0))
    print(x.group('value'))
    

    2、searce()函数

    • 功能
      扫描整个字符串string,并返回第一个pattern模式成功的匹配

    匹配失败 返回 None

    • 参数
      | 参数 | 说明 |
      | ------- | ------------------------------------ |
      | pattern | 匹配的正则表达式(一种字符串的模式) |
      | string | 要匹配的字符串 |
      | flags | 标识位,用于控制正则表达式的匹配方式 |
    import re
    
    res = re.search('[a-z]', '131A3ab889s')
    print(res)
    print(res.group()
    

    3、findall()函数(返回列表)

    参数说明
    pattern匹配的正则表达式(一种字符串的模式)
    string要匹配的字符串
    flags标识位,用于控制正则表达式的匹配方式
    
    myStr = """
    百度
    淘宝
    电
    影网站
    我是倾斜1
    我是倾斜2
    我是倾斜2
    """
    # html里是不区分大小写
    # (1)给正则里面匹配的 加上圆括号 会将括号里面的内容进行 单独的返回
    res = re.findall("((.*?))",myStr) #[('百度', 'baidu', '百度')]
    
    # 括号的区别
    res = re.findall(".*?",myStr) #['百度']
    
    #(2) 不区分大小写的匹配
    res = re.findall(".*?",myStr,re.I) #['百度', '淘宝']
    res = re.findall("<[aA] href=\"http://www\..*?\.com\">.*?",myStr) #['百度']
    

    4、finditer()函数

    功能
    与findall()类似,返回一个迭代器

    参数

    参数说明
    pattern匹配的正则表达式(一种字符串的模式)
    string要匹配的字符串
    flags标识位,用于控制正则表达式的匹配方式
    import re
    
    res = re.finditer('\w', '12hsakda1')
    print(res)
    print(next(res))
    
    for i in res:
        print(i)
    

    5、split()函数

    • 作用:切割字符串
    • 参数
      pattern 正则表达式

    string 要拆分的字符串

    maxsplit 最大拆分次数 默认拆分全部

    flags 修正符

    import re
    myStr = "asdas\rd&a\ts12d\n*a3sd@a_1sd"
    #通过特殊字符 对其进行拆分 成列表
    res = re.split("[^a-z]",myStr)
    res = re.split("\W",myStr)
    

    6、修正符

    • 属性

    re.I 不区分大小写匹配

    print(re.findall('[a-z]','AaBb'))
    print(re.findall('[a-z]','AaBb', flags=re.I))
    

    re.M 多行匹配 影响到^ 和 $ 的功能

    myStr = """asadasdd1\nbsadasdd2\ncsadasdd3"""
    print(re.findall('^[a-z]',myStr, ))
    print(re.findall('\A[a-z]',myStr))
    print(re.findall('\d$',myStr))
    print(re.findall('\d\Z',myStr))
    # re.M
    print(re.findall('^[a-z]',myStr, flags=re.M))
    print(re.findall('\A[a-z]',myStr, flags=re.M))
    print(re.findall('\d$',myStr, flags=re.M))
    print(re.findall('\d\Z',myStr, flags=re.M))
    

    re.S 使.可以匹配换行符 匹配任意字符

    print(re.findall('.*?','b标签'))
    print(re.findall('.*?','b标\n签', flags=re.S))
    

    综合案例

    1、匹配年.txt

    初始文件

    124528	男	14年	2012年5月以前	路人(0)	2017/02/21
    2
    顺便签约客服
    940064306	男	9年	2016/07/12	宗师(1285)	2017/06/26
    3
    世间尽是妖魔鬼怪"(oДo*)
    90年代的新一辈_
    1193887909	男	7年	2016/10/17	宗师(1084)	2017/06/26
    4
    萧十三楼
    905519160	男	9年	2016/07/08	宗师(972)	2017/06/24
    5
    石头哥
    北京-php-石头
    2669288101	男	2年	2016/06/17	宗师(772)	2017/06/23
    6
           缄默。+
           
    1393144035	未知	7年	2016/10/08	宗师(754)	2017/06/25
    7
    

    匹配具体的年

    res = re.findall("\t(\d{1,2}年)",myStr)
    

    匹配具体的年月日

    res = re.findall("[0-9]{4}/[0-9]{2}/[0-9]{2}",myStr)
    

    2、匹配邮箱手机号.txt

    
    	caoxigang@baidu.com
    曹 艳	Caoyan	6895	13811661805	caoyan@baidu.com
    曹 宇	Yu Cao	8366	13911404565	caoyu@baidu.com
    曹 越	Shirley Cao	6519	13683604090	caoyue@baidu.com
    曹 政	Cao Zheng	8290	13718160690	caozheng@baidu.com
    查玲莉	Zha Lingli	6259	13552551952	zhalingli@baidu.com
    查 杉	Zha Shan	8580	13811691291	zhashan@baidu.com
    查 宇	Rachel	8825	13341012971	zhayu@baidu.com
    柴桥子	John	6262	13141498105	chaiqiaozi@baidu.com
    常丽莉	lily	6190	13661003657	changlili@baidu.com
    车承轩	Che Chengxuan	6358	13810729040	chechengxuan@baidu.com
    陈 洁	Che	13811696984	chenxi_cs@baidu.com
    陈 超	allen	8391	13810707562	chenchao@baidu.com
    陈朝辉		13714189826	chenchaohui@baidu.com
    陈 辰	Chen Chen	6729	13126735289	chenchen_qa@baidu.com
    陈 枫	windy	8361	13601365213	chenfeng@baidu.com
    陈海腾	Chen Haiteng	8684	13911884480	chenhaiteng@baidu.com
    陈 红	Hebe	8614	13581610652	chenhong@baidu.com
    陈后猛	Chen Houmeng	8238	13811753474	chenhoumeng@baidu.com
    陈健军	Chen Jianjun	8692	13910828583	chenjianjun@baidu.com
    陈 景	Chen Jing	6227	13366069932	chenjing@baidu.com
    陈竞凯	Chen Jingkai	6511	13911087971	jchen@baidu.com
    陈 坤	Isa13810136756	chenlei@baidu.com
    陈 林	Lin Chen	6828	13520364278	chenlin@qq.com
    
    
    http://bbs.tianya.cn/m/post-140-393974-6.shtml
    http://quote.eastmoney.com/stocklist.html
    http://quote.stockstar.com/stock/sha.shtml
    http://quote.stockstar.com/fund/stock.shtml
    下载链接地址
    http://quotes.money.163.com/service/chddata.html?code=sh202003&end=20130523&fields=TCLOSE;HIGH;LOW;TOPEN;LCLOSE;CHG;PCHG;TURNOVER;VOTURNOVER;VATURNOVER;TCAP;MCAP
    

    #匹配 手机号

    res = re.findall("[1][3-8]\d{9}",myStr)
    

    匹配 邮箱

    res = re.findall("\w+@.+\.\w+",myStr)
    

    匹配豆瓣内容

    标题

    import re
    """
    需求
    1. 豆瓣图书标题
    2. 抓取图片的标签
    """
    
    # 读取数据
    f = open('豆瓣.html','r')
    data = f.read()
    f.close()
    """
    离开的,留下的
    灵契
    寓言
    高难度对话:如何与挑剔的人愉快相处
    """
    # 正则匹配所有标题
     pattern = re.compile('(.*?)')
     titleList = pattern.findall(data)
     print(titleList)
    
    
    

    图片

    import re
    path = r"C:\Users\xlg\Desktop\豆瓣.html"
    file = open(path,"rb")
    data = file.read().decode("utf-8")
    file.close()
    
    # print(data)
    # 
    # 
    # pattern = re.compile("")
    pattern = re.compile("")
    imgList = pattern.findall(data)
    
    # 
    path = r"C:\Users\xlg\Desktop\img.html"
    file = open(path,"w")
    file.writelines(imgList)
    file.close()
    
    

    匹配简介

    import re
    """
    

    [意] 普里莫·莱维 / [意] 莱昂纳多·德·贝内代蒂 / 中信出版社 / 2017-10

    奥斯维辛集中营幸存者的证词合集,由身为化学家的意大利著名作家普里莫·莱维及其奥斯维辛狱友、外科医生德·贝内代蒂共同整理撰写。

    """
    f = open('../素材/豆瓣.html','r') data = f.read() f.close() pattern = re.compile('

    (.*?)

    '
    ,re.DOTALL)
  • 相关阅读:
    无代码开发卡片视图入门教程
    互融云借条APP系统开发 六大系统优势全面保障
    python读取.txt文件中某些关键字后面的内容 并根据该数据画图
    java的生命周期
    移动机器人路径规划(五)--- 基于Minimun Snap的轨迹优化
    Leetcode—136.只出现一次的数字【简单】
    【计算机网络】HTTP协议
    前端开发ui设计稿在网页上的实现
    [JavaScript][AJAX]axios拦截器,axios基地址,get与post区别;实现非空判断;e.preventDefault();事件委托
    postman打开后,以前的接口记录不在,问题解决
  • 原文地址:https://blog.csdn.net/qq_45726327/article/details/140939020