Python正则表达式及模块详解

正则表达式

1.正则表达式

定义:

正则表达式是对字符串操作的一种逻辑公式,我们一般使用正则表达式对字符串进行匹配和过滤。例如,可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

正则表达式是由普通字符和元字符组成。

正则表达式中常见的特殊字符有以下几个:.+?*$^{}\

如果要在正则表达式中表示这几个字符本身,就应该在字符前面加上\。

1.1.1 常用元字符

.                     匹配除换行符以外的任意字符
\w                    匹配数字、字母、下划线,汉字
\s                    匹配任意的一个空白符,如空格,\t,\r,\n等
\d                    匹配任意的一个数字,等价于[0-9]
\n                    匹配一个换行符
\t                    匹配一个制表符
^                     匹配字符串的开始
$                     匹配字符串的结尾
\W                    匹配非(字母、数字、下划线、汉字)
\D                    匹配一个非数字,等价于[^\d],[^0-9]
\S                    匹配非空白符
a|b                   匹配a或b
()                    匹配括号内的表达式,也表示一个组
[...]                 匹配字符组中的其中一个字符
[^...]                匹配一个除了字符组中出现的字符

1.1.2 量词

用于一次性匹配多个字符

*                     表示左边的字符可重复零次或更多次
+                     表示左边的字符可重复一次或更多次
?                    表示左边的字符可重复零次或一次
{n}                   n为整数,表示左边的字符必须且只能重复n次
{n,}                  表示左边的字符最少重复n次或更多次
{n,m}                 表示左边的字符至少重复n次,最多重复m次

1.1.3 量词的用法

'.+'                    匹配任意长度不为0且不含'\n'的字符串。'+'表示左边的'.'代表的任意字符出现一次或更多次。不要求出现的字符都必须一样。
'.*'                    匹配任意不含'\n'的字符串,包括空串。
'[\dac]+'               匹配长度不为0且由数字或'a','c'构成的串,如'451a''a21c78ca''\w{5}'                 匹配长度为5的由数字、字母、下划线、汉字构成的串,如'字母abc''3是_a1'

1.1.4 贪婪匹配&惰性匹配

在量词中的?,*,+,{}都属于贪婪匹配,就是尽可能多的匹配到结果。 在使用.*后面如果加了?,这是尽可能的少匹配。表示惰性匹配。.?.+.{}类似

2.re模块

1.2.1 Match

Match对象是一次匹配的结果,包含了很多关于此次匹配的信息,可以使用Match提供的可读属性或方法来获取这些信息。

属性:

  1. string: 匹配时使用的文本。

  2. re: 匹配时使用的Pattern对象。

  3. pos: 文本中正则表达式开始搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。

  4. endpos: 文本中正则表达式结束搜索的索引。值与Pattern.match()和Pattern.seach()方法的同名参数相同。

  5. lastindex: 最后一个被捕获的分组在文本中的索引。如果没有被捕获的分组,将为None。

  6. lastgroup: 最后一个被捕获的分组的别名。如果这个分组没有别名或者没有被捕获的分组,将为None。

方法:

  1. group([group1, …]): 获得一个或多个分组截获的字符串;指定多个参数时将以元组形式返回。group1可以使用编号也可以使用别名;编号0代表整个匹配的子串;不填写参数时,返回group(0);没有截获字符串的组返回None;截获了多次的组返回最后一次截获的子串。

  2. groups([default]): 以元组形式返回全部分组截获的字符串。相当于调用group(1,2,…last)。default表示没有截获字符串的组以这个值替代,默认为None。

  3. groupdict([default]): 返回以有别名的组的别名为键、以该组截获的子串为值的字典,没有别名的组不包含在内。default含义同上。

  4. start([group]): 返回指定的组截获的子串在string中的起始索引(子串第一个字符的索引)。group默认值为0。

  5. end([group]): 返回指定的组截获的子串在string中的结束索引(子串最后一个字符的索引+1)。group默认值为0。

  6. span([group]): 返回(start(group), end(group))。

  7. expand(template): 将匹配到的分组代入template中然后返回。template中可以使用\id或\g<id>、\g<name>引用分组,但不能使用编号0。\id与\g<id>是等价的;但\10将被认为是第10个分组,如果你想表达\1之后是字符'0',只能使用\g<1>0。

 

 

示例代码:

import re
m = re.match(r'(\w+) (\w+)(?P<sign>.*)', 'hello world!')
​
### output ###
# m.string: hello world!
# m.re: <_sre.SRE_Pattern object at 0x016E1A38>
# m.pos: 0
# m.endpos: 12
# m.lastindex: 3
# m.lastgroup: sign
# m.group(1,2): ('hello', 'world')
# m.groups(): ('hello', 'world', '!')
# m.groupdict(): {'sign': '!'}
# m.start(2): 6
# m.end(2): 11
# m.span(2): (6, 11)
# m.expand(r'\2 \1\3'): world hello!

 

1.2.2 Pattern

Pattern对象是一个编译好的正则表达式,通过Pattern提供的一系列方法可以对文本进行匹配查找。

re模块常用方法:

  1. re.search(pattern, string, flags = 0)

    import re
    res = re.search("\d+", "我今年18岁了,体重为60kg")
    # 输出子串及起止位置
    print(res.group(), res.span())  # 18 (3, 5)
    • 查找字符串中可以匹配成功的字符串,匹配到第一个结果就返回,不会匹配到多个结果

    • 成功则返回一个对象,否则返回 None

       

  2. re.match(pattern, string, flags = 0)

    import re
    result = re.match("\d+","18岁了,我喜欢5个明星")
    print(result.group()) # 18,result.group()是匹配到的字符串
    • 从字符串string的起始位置开始匹配一个模式pattern(即默认加了^),匹配到第一个结果就返回。 (一般用于匹配手机号,邮箱号)

    • 成功则返回一个匹配对象,否则返回None

    • flags 标志位,用于控制模式串的匹配方式,如:是否区分大小写,多行匹配等等。如: re.M | re.I表示忽略大小写,且多行匹配。

       

  3. re.findall(pattern, string, flags = 0)

    list = re.findall("\d+", "我今年18岁了,体重为60kg")
    print(list)  #['18', '60']
    • 查找字符串中所有和模式匹配的子串(不重叠)放入列表。一个子串都找不到就返回空表 [ ]。

       

  4. re.finditer(pattern, string, flags = 0)

    it = re.finditer("\d+", "我今年18岁了,体重为60kg")
    for item in it:
        print(item.group(), item.span())    # 18 (3, 5)     60 (11, 13)
    • 查找字符串中所有和模式匹配的子串(不重叠),每个子串对应于一个匹配对象,返回匹配对象的迭代器。(一般用于爬虫)

       

1.2.3其他操作

  1. split分割

    ret = re.split('[ab]', 'qwerafjbcd')   
    #先按'a'分割,得到'qwer''fjbcd',再对'qwer''fjbcd'分别按'b'分割
    print(ret)          #['qwer', 'fj', 'cd']

     

  2. re.sub(pattern, repl, string, count=0, flags=0) 用于替换匹配的字符串,比str.replace功能更加强大

    ret = re.sub('[a-z]+','sb','武配齐是abc123',)
    print(ret) #武配齐是sb123
    re.sub('\d+','|', 'alex22wupeiqi33oldboy55',count=2) 
    print(ret) #alex|wupeiqi|oldboy55

 

  1. compiler

    obj = re.compile(r'\d{3}')  #将正则表达式编译成为一个 正则表达式对象,规则要匹配的是3个数字
    ​
    obj = re.compile(r'\d+') # 先加载这个正则,后面可以直接用这个正则去匹配内容
    lst = obj.findall("我今天吃了3个馒头,喝了2碗粥")
    print(lst)   # ['3', '2']

 

1.2.4 爬虫必会重点

  • ()括起来的内容是你最终想要的结果

  • (?P正则) 把正则匹配到的内容直接放在name组里面,后面取数据的时候直接group(name)

    obj = re.compile(r"今天吃了(?P<mian>\d+)碗面,又吃了(?P<xian>\d+)盘小咸菜")
    result = obj.finditer("明天我要吃4碗面,喝上8碗汤。今天吃了5碗面,又吃了6盘小咸菜,昨天吃了1碗面条")
    for item in result:
        print(item.group("mian"))       # 5
        print(item.group("xian"))       # 6
        print(item.groupdict())         # {'mian': '5', 'xian': '6'}

 

posted @   楽仔  阅读(256)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
点击右上角即可分享
微信分享提示