python之re模块

描述

该模块提供正则表达式匹配操作。

指导文献

链接:re — Regular expression operations — Python 3.7.13 documentation

使用规则

re为一个模块,如果需要使用该模块中的方法,需要先进行导入,如下所示:

import re

正则表达式语法

​        正则表达式指定一组与其匹配的字符串;这个模块中的函数让你检查一个特定的字符串是否匹配一个给定的正则表达式(或者一个给定的正则表达式是否匹配一个特定的字符串)。

        正则表达式可以串联起来形成新的正则表达式;如果 A 和 B 都是正则表达式,那么 AB 也是正则表达式。一般来说,如果一个字符串 p 匹配 A,另一个字符串 q 匹配 B,则字符串 pq 将匹配 AB。

​         正则表达式可以包含特殊字符和普通字符。大多数普通字符,如“A”、“a”或“0”,都是最简单的正则表达式;他们只是匹配自己。

        一些字符,例如“|”或 '(' 是特殊的。特殊字符要么代表普通字符的类别,要么影响它们周围的正则表达式的解释方式,具体的特殊字符如下所述:

        1) "."(点)

        "."(点)作为通配符,在默认模式下,其能匹配除换行符以外的任何一个字符。 如果指定了re.DOTALL标志,则它匹配任何字符,包括换行符。

        在"foo1\nfoo2\n"中搜索"foo.",匹配结果为['foo1', 'foo2']。但是在"foo1\nfoo2\n"中搜索“foo..”,匹配结果却为空,因为第二个'.'匹配的时候是换行符。在指定re.DOTALL标志的情况下,其匹配结果为['foo1\n', 'foo2\n']。

        2) "^"

        匹配字符串的开头,并且在re.MULTILINE模式下也会在每个换行符之后立即匹配。

        3) "$"

        匹配字符串的结尾或字符串结尾的换行符之前,并且在re.MULTILINE模式下也匹配换行符之前。foo匹配“foo”和“foobar”,而正则表达式 'foo$'只匹配'foo'。

        更有趣的是,在"foo1\nfoo2\n"中搜索foo.$通常匹配 'foo2',但在re.MULTILINE模式下也可以搜索到'foo1';

        在"foo\n"中搜索单个'$'将找到两个空匹配项:一个在换行符之前,一个在字符串末尾,即:['', '']。

        4) "*"

        使生成的RE匹配前一个RE的0个或多个重复,尽可能多的重复,即:[0, +∞)。

        5) "+"

        使生成的 RE匹配前一个RE的1个或多个重复,即:[1, +∞)。

        6) "?"

        使生成的RE匹配前面RE的0或1次重复,即[0, 1]。

        注:"*"、"+"、"?"都是贪婪匹配,也就是尽可能多匹配。但是在其后面加上"?"使其变成惰性匹配,也就是尽可能少匹配。

        "*?":使生成的RE匹配前面RE按照尽可能少的匹配,也就是0个重复;

        "+?":使生成的RE匹配前面RE按照尽可能少的匹配,也就是1个重复;

        "??":使生成的RE匹配前面RE按照尽可能少的匹配,也就是0个重复;

        7) "{}"

        用于匹配前一个字符的重复次数,其可分为如下几种:

        {m} 匹配前一个字符出现m次。

        {m, }匹配前一个字符至少出现m次。如果m等于0,则{0, }就相当于*,如果m等于1,则{0, }就相当于+。

        {, n} 匹配前一个字符至多出现n次。

        {m, n} 匹配前一个字符出现从m~n任何次。但是如果加上"?",即:"{m, n}?",也变成了惰性匹配,按照尽可能少的匹配,最终仅匹配m次。

        8) "[]"

        用于指示一个字符集。在这个字符集中:

  • 字符可以单独列出,例如 [amk] 将匹配 'a'、'm' 或 'k';

  • 字符范围可以通过给出两个字符并用'-'分隔来表示,例:[a-z]将匹配任何小写ASCII字母,[0-5][0-9]将匹配所有两位数字 00 到 59,并且 [0-9A-Fa-f] 将匹配任何十六进制数字。 如果'-'被转义(例:[a-z])或者如果它被放置为第一个或最后一个字符(例如[-a]或[a-]),它将匹配一个文字 '-'。

  • 特殊字符在集合中失去其特殊意义。例:[(+*)] 将匹配任何文字字符 '('、'+'、'*' 或 ')'。

  • 不在一个范围内的字符可以通过补集来匹配。 如果集合的第一个字符是'^',那么所有不在集合中的字符都将被匹配。 例如,[^5]将匹配除 '5' 之外的任何字符,而 [^^] 将匹配除 '^' 之外的任何字符。 如果 ^ 不是集合中的第一个字符,则 ^ 没有特殊含义。

  • 要匹配集合内的文字 ']',请在其前面加上反斜杠,或将其放在集合的开头。 例如,[()[\]{}] 和 []()[{}] 都将匹配括号。

    9) "|"

    A|B,其中 A 和 B 可以是任意 RE,创建将匹配 A 或 B 的正则表达式。

    10) "()"

    匹配括号内的任何正则表达式。 要匹配文字 '(' 或 ')',请使用 ( 或 ),或将它们包含在字符类中:[(], [)]。

    11) "(?P<name>...)"

    类似于常规括号,但组匹配的子字符串可通过符号组名称访问,即<>中的名称。组名必须是有效的 Python 标识符,并且每个组名只能在正则表达式中定义一次。符号组也是一个编号组,就好像该组没有命名一样。

        12) "\"

        "\"为特殊转义符,其与下面的字符共同组成实现特殊功能。如果普通字符不是 ASCII 数字或 ASCII 字母,则生成的 RE 将匹配第二个字符。 例:\$ 匹配字符"$"。

元字符匹配内容
\数字匹配相同数字组的内容
\A仅匹配字符串的开头。
\Z仅匹配字符串的结尾。
\d匹配任何十进制数字,等效于集合 [0-9]。
\D匹配任何非十进制数字,等效于集合 [^0-9]或[^\d]。
\s匹配任何空白字符,等效于集合[ \t\n\r\f\v]。
\S匹配任何空非白字符,等效于集合[^ \t\n\r\f\v]。
\w匹配任何数字字母字符,等效于集合[a-zA-Z0-9_]。
\W匹配任何非数字字母字符,等效于集合[^a-zA-Z0-9_]
\b匹配一个单词边界,也就是指单词和空格间的位置。\b 被定义为 \w 和 \W 字符之间的边界,或 \w 和字符串的开头/结尾之间的边界。 这意味着 r'\bfoo\b' 匹配 'foo'、'foo.'、'(foo)'、'bar foo baz' ,但不匹配 'foobar' 或 'foo3'。
\B匹配非单词边界,也就是指单词非结束和开始的位置。\B与\b是相反操作,'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。

模块内置方法(V3.7)

  • re.compile(pattern, flags=0)

用途:将正则表达式模式编译成正则表达式对象,可用于其他方法(需要使用正则表达式对象的方法)进行匹配,如下所述。

返回值:正则表达式对象。

        其中,

        参数pattern -- 正则表达式。

        参数flags -- 用于修改正则表达式的行为,其值可以是一下任何变量,且可以使用'|'进行组合,详情如下表所示。

属性含义
re.A (re.ASCII)对于字符串模式,使 \w、\W、\b、\B、\d、\D 匹配相应的 ASCII 字符类别,这仅对Unicode模式有意义,而对于字节模式则忽略。
re.I(re.IGNORECASE)执行不区分大小写的匹配;类似表达式[A-Z]也将匹配小写字母。
re.L(re.LOCALE)让\w,\W,\b,\B和区分大小写的匹配取决于当前的语言环境。该标志只能与字节模式一起使用。不建议使用此标志,因为语言环境机制非常不可靠,它一次只能处理一种“区域性”,并且仅适用于8位语言环境。默认情况下,Python 3中已为Unicode(str)模式启用了Unicode匹配,并且能够处理不同的语言环境/语言。
re.M(re.MULTILINE)指定时,模式字符'^'在字符串的开头和每行的开头(紧随每个换行符之后)匹配;模式字符'$' 在字符串的末尾和每行的末尾(紧接在每个换行符之前)匹配。默认情况下,'^' 仅在字符串的开头,字符串'$'的末尾和字符串末尾的换行符(如果有)之前立即匹配。
re.S(re.DOTALL)使'.'特殊字符与任何字符都匹配,包括换行符;没有此标志,'.'将匹配除换行符以外的任何内容。
re.DEBUG显示有关已编译表达式的调试信息。 没有对应的内联标志。

例:

import re
prog = re.compile(pattern) #返回的正则表达式对象有两种使用方式
#compile返回的正则表达式的第一种使用方式
result = prog.match(string) #可直接通过正则表达式对象prog引用re中的方法
#compile返回的正则表达式的第二种使用方式
result = re.match(prog, string)
#上述正则表达水也可不需要使用compile进行处理
result = re.match(pattern, string) #与上述两种都是等同关系
  • re.findall(pattern, string, flags=0)

用途:通过正则表达式匹配字符串中所有匹配项。

返回值:返回字符串中所有非重叠匹配的列表。从左到右扫描字符串,并按找到的顺序返回匹配项。如果模式中存在一个或多个组,则返回组列表;如果模式有多个组,这将是一个元组列表。结果中包含空匹配项。

        其中,

        参数pattern -- 正则表达式。

        参数string -- 需要被匹配的字符串。

        参数flags -- 详情参见re.compile()方法。

例:

>>> import re
#例1 "."
>>> re.findall("foo.", "foo1\nfoo2\n")
['foo1', 'foo2'] #输出结果
>>> re.findall("foo..", "foo1\nfoo2\n") 
[] #输出结果,因为第二"."匹配的换行符,而"."默认不能匹配换行符
>>> re.findall("foo..", "foo1\nfoo2\n", re.DOTALL)
['foo1\n', 'foo2\n'] #输出结果,因为flags设置了模式DOTALL,"."可以匹配换行符
​
#例2 "^"
>>> re.findall("^foo.", "foo1\nfoo2\n")
['foo1'] #输出结果,默认不能换行匹配
>>> re.findall("^foo.", "foo1\nfoo2\n", re.MULTILINE)
['foo1', 'foo2'] #输出结果,flags设置为MULTILINE,"^"可以匹配换行符
​
#例3 "$"
>>> re.findall("foo.$", "foo1\nfoo2\n")
['foo2'] #输出结果
>>> re.findall("foo.$", "foo1\nfoo2\n", re.MULTILINE)
['foo1', 'foo2'] #输出结果,flags设置为MULTILINE,"$4"可以匹配换行符
​
#例4 "*"
>>> re.findall("python*", "abdsdfpythonnnnnnn")
['pythonnnnnnn'] #输出结果
>>> re.findall("python*", "abdsdfpytho")
['pytho'] #输出结果
​
#例5 "+"
>>> re.findall("python+", "abdsdfpythonnnnnnn")
['pythonnnnnnn'] #输出结果
>>> re.findall("python+", "abdsdfpytho")
[] #输出结果
​
#例6 "?"
>>> re.findall("python?", "abdsdfpythonnnnnnn")
['python'] #输出结果,可匹配(0, 1)个n
>>> re.findall("python?", "abdsdfpytho")
['pytho'] #输出结果,可匹配(0, 1)个n
​
#例7 "{}"
>>> re.findall("python{4}", "abdsdfpythonnn")
[] #输出结果,需要匹配4个n,因为没有,所以匹配失败
>>> re.findall("python{0,}", "abdsdfpythonnn")
['pythonnn'] #输出结果,匹配n的个数0到无穷
>>> re.findall("python{0,5}", "abdsdfpythonnnnnnnn")
['pythonnnnn'] #输出结果,匹配n的个数0到5
>>> re.findall("python{,2}", "abdsdfpythonnnnnnnn")
['pythonn'] #输出结果,匹配n的个数最大2个
​
#例8 "[]"
>>> re.findall("[a-z]", "123python456")
['p', 'y', 't', 'h', 'o', 'n'] #输出结果
>>> re.findall("[\[\]]", "123[python]456")
['[', ']'] #输出结果
​
#例9 "*?" "+?" "??"
>>> re.findall("python*?", "abdsdfpythonnn")
['pytho'] #输出结果,n的个数最少可以为0个
>>> re.findall("python+?", "abdsdfpythonnn")
['python'] #输出结果,n的个数最少可以为1个
>>> re.findall("python??", "abdsdfpythonnn")
['pytho'] #输出结果,n的个数最少可以为0个
​
#例10 "\b" "\B"
>>> re.findall(r"\bI\b", "hello I am")
['I'] #输出结果,匹配一个单词边界,也就是指单词和空格间的位置
>>> re.findall(r"\BI\B", "hello I am")
[] #输出结果,匹配非单词边界,也就是指单词非结束和开始的位置
>>> re.findall(r"\bI\b", "helloIam")
[] #输出结果
>>> re.findall(r"\BI\B", "helloIam")
['I'] #输出结果
  • re.search(pattern, string, flags=0)

用途:扫描字符串寻找正则表达式模式产生匹配的第一个位置

返回值:返回相应的Match对象。如果字符串中没有位置与模式匹配,则返回 None。

        其中,

        参数pattern -- 正则表达式。

        参数string -- 需要被匹配的字符串。

        参数flags -- 详情参见re.compile()方法。

例:

>>> import re
#例1
>>> result = re.search("[a-z]+", "xiaoming18wwwwxiaoming19dddxiaoming20")
>>> result
<re.Match object; span=(0, 8), match='xiaoming'> #输出结果,为匹配对象,范围是0-8,仅仅匹配第一个xiaoming
# 可以通过Match.group()返回匹配的一个或多个子组。如果只有一个参数,则结果为单个字符串; 如果有多个参数,则结果是一个元组,每个参数一个item。
>>> result.group() 
'xiaoming'
#对于Match.group()而言,如果正则表达式使用(?P<name>...)语法,则groupN参数也可以是通过组名标识组的字符串。如果字符串参数未用作模式中的组名,则会引发 IndexError 异常。
#例2
>>> result = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "xiaoming18wwwwxiaoming19dddxiaoming20")
>>> result.group("name") #用"name"作为索引,如果没有?P<name>语句,则不可以使用"name"作为索引
'xiaoming'
>>> result.group("age") #用"age"作为索引
'18'
>>> result.group("name", "age")
('xiaoming', '18')
>>> result.group(1, 2) #也可以用数字进行索引,数字默认可以作为索引
('xiaoming', '18')
>>> result.group(1) #1:表示正则表达式中符合条件的字符串中的第一个() 中的字符串。
'xiaoming'
>>> result.group(2) #2:表示正则表达式中符合条件的字符串中的第二个() 中的字符串。以此类推
'18'
>>> result.group(0) #0:表示正则表达式中符合条件的字符串。
'xiaoming18'
  • re.match(pattern, string, flags=0)

用途:从头匹配一个符合规则的字符串,从起始位置开始匹配。

返回值:返回一个 Match 对象,如果没有找到匹配项,则返回 None。

        其中,

        参数pattern -- 正则表达式。

        参数string -- 需要被匹配的字符串。

        参数flags -- 详情参见re.compile()方法。

例:

>>> import re
#例1
>>> result = re.match("(?P<name>[a-z]+)(?P<age>\d+)", "xiaoming18wwwwxiaoming19dddxiaoming20")
>>> result.group("name") #用"name"作为索引,如果没有?P<name>语句,则不可以使用"name"作为索引
'xiaoming'
>>> result.group("age") #用"age"作为索引
'18'
>>> result.group("name", "age")
('xiaoming', '18')
>>> result.group(1, 2) #也可以用数字进行索引,数字默认可以作为索引
('xiaoming', '18')
>>> result.group(1) #1:表示正则表达式中符合条件的字符串中的第一个() 中的字符串。
'xiaoming'
>>> result.group(2) #2:表示正则表达式中符合条件的字符串中的第二个() 中的字符串。以此类推
'18'
>>> result.group(0) #0:表示正则表达式中符合条件的字符串。
'xiaoming18'
​
#例2
#re.match的例1和re.search的例2的输出结果是一样的,那么它们的区别到底是啥?re.match是从起始位置开始匹配,而re.search是匹配到第一个就停止。
>>> result = re.match("(?P<name>[a-z]+)(?P<age>\d+)", "Zxiaoming18wwwwxiaoming19dddxiaoming20")
>>> result.group(0)  #输出结果,因为没有匹配成功,返回的是None,因此报'NoneType'的错误
Traceback (most recent call last):
  File "<pyshell#39>", line 1, in <module>
    result.group(0)
AttributeError: 'NoneType' object has no attribute 'group'
>>> result = re.search("(?P<name>[a-z]+)(?P<age>\d+)", "Zxiaoming18wwwwxiaoming19dddxiaoming20")
>>> result.group(0)
'xiaoming18' #输出结果,与re.match的匹配结果不一样。
>>> 
  • re.split(pattern, string, maxsplit=0, flags=0)

用途:按模式的出现拆分源字符串。

返回值:返回包含结果子字符串的列表。

​        其中,

        参数pattern -- 正则表达式。

        参数string -- 需要被匹配的字符串。

        参数maxsplit -- 最大拆分次数,如果 maxsplit 不为零,则最多发生 maxsplit 拆分,并将字符串的其余部分作为列表的最后一个元素返回。

        参数flags -- 详情参见re.compile()方法。

例:

>>> import re
#例1
>>> re.split(r"\d+", "Zxiaoming18wwwwxiaoming19dddxiaoming20") 
['Zxiaoming', 'wwwwxiaoming', 'dddxiaoming', '']
​
#例2
>>> re.split(r"(\d+)", "Zxiaoming18wwwwxiaoming19dddxiaoming20") #()表示默认保留分隔符
['Zxiaoming', '18', 'wwwwxiaoming', '19', 'dddxiaoming', '20', ''] #输出结果,含有分隔符
​
#例3
>>> re.split(r"\d+", "Zxiaoming18wwwwxiaoming19dddxiaoming20", 1) #maxsplit配置为1
['Zxiaoming', 'wwwwxiaoming19dddxiaoming20'] #输出结果
​
#例4
>>> re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)
['0', '3', '9']
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

5G加油站

你的鼓励是创造的最大动力。

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

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

打赏作者

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

抵扣说明:

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

余额充值