Python之正则表达式

正则表达式(Regular Experssion)使⽤单个字符串来描述、匹配⼀系列匹配某个句法规则的字符串,通常被⽤来检索、替换那些匹配某个模式的⽂本。

正则表达式匹配规则

单字符匹配规则:

字符 功能
. 匹配任意1个字符,除了\n换行符
[] 匹配[]中列举的字符
\d 匹配数字,即0-9
\D 匹配非数字
\s 匹配空白,即空格或tab键
\S 匹配非空白
\w 匹配单词字符,及a-z,A-Z,0-9,_
\W 匹配非单词字符

多个字符匹配规则:

字符 功能
* 匹配前⼀个字符出现0次或者⽆限次,即可有可⽆
+ 匹配前⼀个字符出现1次或者⽆限次,即⾄少有1次
? 匹配前⼀个字符出现1次或者0次,即要么有1次,要么没有
{m} 匹配前⼀个字符出现m次
{m,} 匹配前⼀个字符⾄少出现m次
{m,n} 匹配前⼀个字符出现从m到n次

表示边界的规则:

字符 功能
^ 匹配字符串开头
$ 匹配字符串结尾
\b 匹配⼀个单词的边界
\B 匹配⾮单词边界

匹配分组:

可以用圆括号将要提取的数据包住,通过 .group()获取

字符 功能
| 匹配左右任意⼀个表达式
(ab) 将括号中字符作为⼀个分组
\num 引⽤分组num匹配到的字符串
(?P) 分组起别名
(?P=name) 引⽤别名为name分组匹配到的字符串

注意的知识点:

  • Python中字符串前面加上r表示原生字符串,这样针对转义字符串就不用加”"了,不用担心是否漏写”"了。
    1
    2
    3
    4
    5
    6
    >>> ret = re.match("c:\\\\a",mm).group()
    >>> print(ret)
    c:\a
    >>> ret = re.match(r"c:\\a",mm).group()
    >>> print(ret)
    c:\a
  • python的贪婪模式
    Python⾥数量词默认是贪婪的,总是尝试匹配尽可能多的字符;正则表达式模式中使⽤到通配字,那它在从左到右的顺序求值时,会尽量“抓取”满⾜匹配最⻓字符串
    解决⽅式:⾮贪婪操作符“?”,这个操作符可以⽤在”*”,”+”,”?”,”{m,n}”的后⾯,要求正则匹配的越少越好。
    1
    2
    3
    4
    >>> re.match(r"aa(\d+)","aa2343def").group(1)
    '2343'
    >>> re.match(r"aa(\d+?)","aa2343def").group(1)
    '2'

Python之re模块的使用

在Python使用正则表达式,可调用re模块。

match方法

使用match方法进行匹配,若字符串匹配正则表达式,则match方法返回匹配对象,否则返回None(注意不是空字符串””)。匹配对象具有group方法,用来返回字符串的匹配部分。
re.match() 能够匹配出以xxx开头的字符串,即从头开始匹配字符串。

1
2
3
4
5
# 使用match方法进行匹配操作
result = re.match(正则表达式,要匹配的字符串)

# 如果上一步匹配到数据的话,可以使用group方法来提取数据
result.group()
1
2
3
4
5
6
7
8
9
10
>>> result = re.match("\w*","Python666@126.com")
>>> result.group()
'Python666'
>>> ret = re.match("(\w*)@(\d*)","Python666@126.com")
>>> ret.group(1)
'Python666'
>>> ret.group(2)
'126'
>>> re.match(r"(\w*://[\w\.]*/)","https://movie.douban.com/cinema/nowplaying/beijing/").group(1)
'https://movie.douban.com/'

search方法

返回一个对象,可用group()取值。

1
2
3
4
5
>>> ret = re.search(r"\d+", "阅读次数为 999")
>>> ret.group()
'999'
>>> re.search(r"\d+\.?\d*","Zero-point energy E_ZPE (eV): 0.45747").group()
'0.45747'

findall方法

返回包含匹配到的所有字符串的一个列表。

1
2
3
>>> ret = re.findall(r"\d+", "python = 999, c = 890, c++ = 1245")
>>> print(ret)
['999', '890', '1245']

sub方法

re.sub(正则表达式, 替换字符串, 要匹配的字符串),返回替换后的整个字符串。

1
2
3
>>> ret = re.sub(r"\d+", '520', "python = 996")
>>> ret
'python = 520'
1
2
3
4
5
6
7
8
9
10
>>> import re
>>> def add(temp):
... strNum = temp.group()
... num = int(strNum) + 2
... return str(num)
...
>>> ret = re.sub(r"\d+", add, "python = 997")
>>> ret
'python = 999'
>>>

split方法

根据匹配进⾏切割字符串,并返回⼀个列表

1
2
3
>>> ret = re.split(r":| ","个人信息:吒儿 3岁 陈塘关")
>>> ret
['个人信息', '吒儿', '3岁', '陈塘关']

compile方法

对于经常要用到的正则表达式,可以使用compile进行编译,后期可以直接调用。

1
2
3
4
>>> text = "Zero-point energy E_ZPE (eV):  0.45747"
>>> digit = re.compile('\d+\.?\d*')
>>> re.search(digit,text).group()
'0.45747'

compile可以指定flag=re.VERBOSE,在写正则表达式时可以添加注释。在写多行的正则表达式时,可以用左右各三个双引号引起来。

1
2
3
4
5
6
7
8
text = "Zero-point energy E_ZPE (eV):  0.45747"
digit = re.compile(r"""
\d+ # 小数点前面的数字
\.? # 小数点本身
\d* # 小数点后面的数字
""",re.VERBOSE)
result = re.search(digit,text)
print(result.group())