Python 正则表达式

简介: 本文介绍 Python 中正则表达式相关知识。

Python 正则表达式


李俊才的个人博客

已入驻阿里云

邮箱 :291148484@163.com
本文地址
- https://developer.aliyun.com/article/
- https://blog.csdn.net/qq_28550263/article/details/123482797

相关文章推荐


目 录


1. 概述

2. 字符串规则描述符

3. Python 的re模块


1. 概述

正则表达式用于描述各种复杂的字符串关系,使用正则表达式能够更加灵活便捷地处理字符串。

2. 字符串规则描述符

2.1 定位符:描述字符的边界

符号 描述 说明
^ 匹配一个字符串的起始字符 -
$ 匹配一个字符串的结尾字符 -
\b 匹配一个单词的边界 -
\B 匹配单词边界 相当于\b匹配的反集

2.2 限定符:描述重复匹配的次数

符号 描述 说明
? 匹配该限定符前的字符01 colou?r 可以匹配colourcolor
+ 匹配该限定符前的字符1 hel+o可以匹配helohellohelllo、…
* 匹配该限定符前的字符0 hel*o可以匹配heohelohellohelllo、…
{n} 匹配该限定符前的字符n hel{2}o只可以匹配hello
{n,} 匹配该限定符前的字符最少n次 hel{2,}o可以匹配hellohelllo、…
{n,m} 匹配该限定符前的字符最少n次最多m次 hel{2,3}o只可以匹配hellohelllo

【例】写出从字符串string的任意一行中匹配颜色名颜色值的正则表达式:

# 待提取的字符串string='''$navajowhite:          #FFDEAD !default;$moccasin:             #FFE4B5 !default;$bisque:               #FFE4C4 !default;$mistyrose:            #FFE4E1 !default;$blanchedalmond:       #FFEBCD !default;$lavenderblush:        #FFF0F5 !default;'''
目标 表达式 说明
提取颜色名 r'\w{1,15} 考虑到上面颜色名单词最长没有超过15个字符串,最短肯定得有字符,所以写了{1,15},但也可以是其它的合理值即可。
提取颜色值 r'#.{6}', 颜色值由#符号开头,一共由六位十六进制数字,十六进制数字为是个阿拉伯数字字符加A、B、C、D、E、F五个英文字符构成。

2.3 字符描述

符号 描述 说明
\d 匹配任意数字
\s 匹配任意空白符
\w 匹配任意字母、数字、下划线、汉字等
\D 匹配任意数字
\S 匹配任意空白符
\W 匹配除了字母、数字、下划线、汉字以外的字符
. 匹配除了换行符以外的任意字符
形式 描述 说明
[A-Z] 区间匹配,匹配字母表该区间所有大写字母 [C-F]匹配字符C、D、E、F
[a-z] 区间匹配,匹配字母表该区间所有小写字母 [c-f]匹配字符c、d、e、f
[0-9] 区间匹配,匹配该区间内的所有数字 [3-6]匹配字符3、4、5、6
[ABCD] 列表匹配,匹配[]中列出的所有字母 如这里列出的A、B、C、D都会被匹配
[^ABCD] 列表排除,匹配除了[]中列出的字符外的所有字符 如这里列出的A、B、C、D都会被排除而匹配其它字符

例如,匹配IPV4地址:

import re
url = 'https://127.0.0.1:8888/notebooks/Untitled.ipynb'
res = re.compile(r'[1-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[1-9]{1,3}').findall(url)[0]

2.4 管道符:使用“或”匹配逻辑

管道符就是一根竖线:|,再正则表达式中标识”或“。由于匹配方向时从左向右进行的,假如有两个正则表达式AB,那么使用 A|B 匹配字符串时,只要前一个样式完全匹配成功,那么后一个就不再匹配。

2.5 转义字符:将特殊符号标识为普通字符

在正则表达式中用于标识特殊含义的符号如.用于标识一个任意的非换行符字符,^标识起始字符,等等。但是我们希望匹配到这些字符本身也是经常遇到的情况,如IPV4地址使用.作为分割符。因此我们如果需要完整提取IPV4地址就需要表示.本身。由于直接使用点已经有了其它的含义,因此我们使用一个\号进行转义,即使用\.来表示点(.)。其它在正则中有特殊含义的符号也可以使用类似的方式。

2.6 分组

与数学计算中采用小括号()进行算式分组一样,正则模板也能够分组表达,目的是将某一部分正则模板作为一个整体表达,例如模板:

importres='4aderf weew16a dawedb_ewwecs aswed 6aew'res_1=re.compile(r'(we|ew){1}').findall(s)
res_2=re.compile(r'(we|ew){2}').findall(s)
print(res_1,res_2)

Out[]: [‘we’, ‘ew’, ‘we’, ‘ew’, ‘we’, ‘we’, ‘ew’] [‘ew’, ‘we’]

这里将(we|ew)作为一个组,{n}对改组指定重复匹配的次数。

2.7 flags修饰符

在Python的re模块中很多方法都可以指定一个flags参数作为标志位,通过指定这个参数值能够实现一些特殊的功能,详见 3.1 常量 小节。

3. Python 的re模块 API

3.1 常量

常量 简写/相同功能 描述
re.ASCII re.A 用作标志位的 flag,让 \w, \W, \b, \B, \d, \D, \s 和 \S 只匹配ASCII,而不是Unicode。
re.DEBUG - 显示编译时的debug信息,没有内联标记。
re.IGNORECASE re.I 用作标志位的 flag,进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。
re.LOCALE re.L 用作标志位的 flag,由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。
re.MULTILINE re.M 用作标志位的 flag,设置^$用于包括整个字符串的开始和结尾的每一行。
re.DOTALL re.S 用作标志位的 flag,让 ‘.’ 特殊字符匹配任何字符,包括换行符。
re.VERBOSE re.X 用作标志位的 flag,这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。

3.1.1 re.ASCII

\w, \W, \b, \B, \d, \D, \s\S 只匹配ASCII,而不是Unicode。这只对Unicode样式有效,会被byte样式忽略。相当于前面语法中的内联标志 (?a) 。

3.1.2 re.DEBUG

显示编译时的debug信息,没有内联标记。

3.1.3 re.IGNORECASE

进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符。Unicode匹配(比如 Ü 匹配 ü)同样有用,除非设置了 re.ASCII 标记来禁用非ASCII匹配。当前语言区域不会改变这个标记,除非设置了 re.LOCALE 标记。这个相当于内联标记 (?i)

3.1.4 re.LOCALE

由当前语言区域决定 \w, \W, \b, \B 和大小写敏感匹配。这个标记只能对byte样式有效。这个标记不推荐使用,因为语言区域机制很不可靠,它一次只能处理一个 "习惯”,而且只对8位字节有效。Unicode匹配在Python 3 里默认启用,并可以处理不同语言。 这个对应内联标记 (?L)

3.1.5 re.MULTILINE

设置^$用于包括整个字符串的开始和结尾的每一行。默认情况下,’^’ 匹配字符串头,'$' 匹配字符串尾。对应内联标记 (?m)

3.1.6 re.DOTALL

'.' 特殊字符匹配任何字符,包括换行符;如果没有这个标记,'.' 就匹配 除了 换行符的其他任意字符。对应内联标记 (?s)

3.1.7 re.VERBOSE

这个标记允许你编写更具可读性更友好的正则表达式。通过分段和添加注释。空白符号会被忽略,除非在一个字符集合当中或者由反斜杠转义,或者在 *?, (?: 或者(?P<…> 分组之内。当一个行内有 # 不在字符集和转义序列,那么它之后的所有字符都是注释。

3.2 正则方法

方法 描述
re.compile(pattern, flags=0) 将正则表达式的样式编译为一个 正则表达式对象 (正则对象)
re.search(pattern, string, flags=0) 扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象
re.match(pattern, string, flags=0) 如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None
re.fullmatch(pattern, string, flags=0) 如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象
re.split(pattern, string, maxsplit=0, flags=0) pattern 分开 string
re.findall(pattern, string, flags=0) 以字符串或元组的形式返回字符串中模式的所有非重叠匹配
re.finditer(pattern, string, flags=0) patternstring 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象
re.sub(pattern, repl, string, count=0, flags=0) 返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串
re.subn(pattern, repl, string, count=0, flags=0) 作用与 sub() 相同,但是返回一个元组 (字符串, 替换次数)
re.escape(pattern) 转义 pattern 中的特殊字符
re.purge() 用于清除正则表达式的缓存

3.2.1 re.compile 方法

扫描整个 字符串 找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个 None ; 注意这和找到一个零长度匹配是不同的。

1. 调用格式

格式 参数
re.compile(pattern, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importre

3.2.2 re.search 方法

如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。

注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。

1. 调用格式

格式 参数
re.search(pattern, string, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

import re

3.2.3 re.match 方法

如果 string 开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回 None ;注意它跟零长度匹配是不同的。

注意即便是 MULTILINE 多行模式, re.match() 也只匹配字符串的开始位置,而不匹配每行开始。

1. 调用格式

格式 参数
re.match(pattern, string, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importrere.match(
r'mr_\w+',               # pattern'HELLO_EORLD hello_world',       # stringre.I# flag)

Out[]: <re.Match object; span=(0, 11), match=‘HELLO_EORLD’>

3.2.4 re.fullmatch 方法

如果整个 string 匹配到正则表达式样式,就返回一个相应的 匹配对象 。 否则就返回一个 None ;注意这跟零长度匹配是不同的。

1. 调用格式

格式 参数
re.fullmatch(pattern, string, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importre

3.2.5 re.split 方法

用 pattern 分开 string 。 如果在 pattern 中捕获到括号,那么所有的组里的文字也会包含在列表里。如果 maxsplit 非零, 最多进行 maxsplit 次分隔, 剩下的字符全部返回到列表的最后一个元素。

1. 调用格式

格式 参数
re.split(pattern, string, maxsplit=0, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importrere.split(r'\W+', 'Words, words, words.')           # ['Words', 'words', 'words', '']re.split(r'(\W+)', 'Words, words, words.')         # ['Words', ', ', 'words', ', ', 'words', '.', '']re.split(r'\W+', 'Words, words, words.', 1)        # ['Words', 'words, words.']re.split('[a-f]+', '0a3B9', flags=re.IGNORECASE)   # ['0', '3', '9']

如果分隔符里有捕获组合,并且匹配到字符串的开始,那么结果将会以一个空字符串开始。对于结尾也是一样:

re.split(r'(\W+)', '...words, words...')           # ['', '...', 'words', ', ', 'words', '...', '']

这样的话,分隔组将会出现在结果列表中同样的位置。样式的空匹配仅在与前一个空匹配不相邻时才会拆分字符串。

re.split(r'\b', 'Words, words, words.')      # ['', 'Words', ', ', 'words', ', ', 'words', '.']re.split(r'\W*', '...words...')              # ['', '', 'w', 'o', 'r', 'd', 's', '', '']re.split(r'(\W*)', '...words...')            # ['', '...', '', '', 'w', '', 'o', '', 'r', '', 'd', '', 's', '...', '', '', '']

3.2.6 re.findall 方法

以字符串或元组的形式返回字符串中模式的所有非重叠匹配。从左到右扫描字符串,匹配项按找到的顺序返回。结果中包含空匹配。

结果取决于模式中捕获组的数量。如果没有组,则返回匹配整个模式的字符串列表。如果只有一个组,则返回与该组匹配的字符串列表。如果存在多个组,则返回与这些组匹配的字符串元组列表。非捕获组不影响结果的形式。

1. 调用格式

格式 参数
re.findall(pattern, string, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importrere.findall(r'\bf[a-z]*', 'which foot or hand fell fastest')

Out[]:[‘foot’, ‘fell’, ‘fastest’]

3.2.7 re.finditer 方法

pattern 在 string 里所有的非重复匹配,返回为一个迭代器 iterator 保存了 匹配对象 。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。

1. 调用格式

格式 参数
re.finditer(pattern, string, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

importre

3.2.8 re.sub 方法

返回通过使用 repl 替换在 string 最左边非重叠出现的 pattern 而获得的字符串。 如果样式没有找到,则不加改变地返回 string。 repl 可以是字符串或函数;如为字符串,则其中任何反斜杠转义序列都会被处理。 也就是说,\n 会被转换为一个换行符,\r 会被转换为一个回车符,依此类推。 未知的 ASCII 字符转义序列保留在未来使用,会被当作错误来处理。 其他未知转义序列例如 & 会保持原样。 向后引用像是 \6 会用样式中第 6 组所匹配到的子字符串来替换。

如果 repl 是一个函数,那它会对每个非重复的 pattern 的情况调用。这个函数只能有一个 匹配对象 参数,并返回一个替换后的字符串。

1. 调用格式

格式 参数
re.sub(pattern, repl, string, count=0, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

以下例子来源于Python标准库:

importrere.sub(r'def\s+([a-zA-Z_][a-zA-Z_0-9]*)\s*\(\s*\):',
...        r'static PyObject*\npy_\1(void)\n{',
...        'def myfunc():')

Out[]:‘static PyObject*\npy_myfunc(void)\n{’

def dashrepl(matchobj):
    if matchobj.group(0) == '-': 
        return ' '
    else: 
        return '-'
re.sub('-{1,2}', dashrepl, 'pro----gram-files')                         # 'pro--gram files'
re.sub(r'\sAND\s', ' & ', 'Baked Beans And Spam', flags=re.IGNORECASE)  # 'Baked Beans & Spam'

3.2.9 re.subn 方法

1. 调用格式

格式 参数
re.subn(pattern, repl, string, count=0, flags=0)
pattern:编译时使用的表达式字符串
flags:编译标志为。用于修改正则表达式的匹配方式,详见 2.7节 flags修饰符

2. 小例子

import re

3.2.10 re.escape 方法

1. 调用格式

格式 参数
re.escape(pattern)
pattern:编译时使用的表达式字符串

2. 小例子

以下例子来源于Python标准库:

importreprint(re.escape('https://www.python.org'))  # https://www\.python\.orglegal_chars=string.ascii_lowercase+string.digits+"!#$%&'*+-.^_`|~:"print('[%s]+'%re.escape(legal_chars))     # [abcdefghijklmnopqrstuvwxyz0123456789!\#\$%\&'\*\+\-\.\^_`\|\~:]+operators= ['+', '-', '*', '/', '**']
print('|'.join(map(re.escape, sorted(operators, reverse=True))))
/|\-|\+|\*\*|\*

3.2.11 re.purge 方法

调用格式

格式 参数
re.purge()
目录
相关文章
|
4月前
|
Python
"揭秘!Python如何运用神秘的正则表达式,轻松穿梭于网页迷宫,一键抓取隐藏链接?"
【8月更文挑战第21天】Python凭借其强大的编程能力,在数据抓取和网页解析领域表现出高效与灵活。通过结合requests库进行网页请求及正则表达式进行复杂文本模式匹配,可轻松提取网页信息。本示例展示如何使用Python和正则表达式解析网页链接。首先确保已安装requests库,可通过`pip install requests`安装。接着,利用requests获取网页内容,并使用正则表达式提取所有`&lt;a&gt;`标签的`href`属性。
57 0
|
1月前
|
Python
在Python中,可以使用内置的`re`模块来处理正则表达式
在Python中,可以使用内置的`re`模块来处理正则表达式
53 5
|
1月前
|
数据采集 Web App开发 iOS开发
如何使用 Python 语言的正则表达式进行网页数据的爬取?
使用 Python 进行网页数据爬取的步骤包括:1. 安装必要库(requests、re、bs4);2. 发送 HTTP 请求获取网页内容;3. 使用正则表达式提取数据;4. 数据清洗和处理;5. 循环遍历多个页面。通过这些步骤,可以高效地从网页中提取所需信息。
|
2月前
|
Python
【收藏备用】Python正则表达式的7个实用技巧
【收藏备用】Python正则表达式的7个实用技巧
33 1
|
2月前
|
数据安全/隐私保护 Python
Python实用正则表达式归纳
Python实用正则表达式归纳
20 3
|
2月前
|
Python
Python 正则表达式高级应用指南
正则表达式是文本模式匹配的强大工具,Python 的 `re` 模块支持其操作。本文介绍正则表达式的高级应用,包括复杂模式匹配(如邮箱、电话号码)、分组与提取、替换操作、多行匹配以及贪婪与非贪婪模式的区别。通过示例代码展示了如何灵活运用这些技巧解决实际问题。
33 7
|
2月前
|
JavaScript 前端开发 Scala
Python学习十:正则表达式
这篇文章是关于Python中正则表达式的使用,包括re模块的函数、特殊字符、匹配模式以及贪婪与非贪婪模式的详细介绍。
21 0
|
2月前
|
数据采集 开发者 Python
Python正则表达式之re.compile函数
`re.compile`是Python正则表达式处理中一个强大的工具,它通过预先编译正则表达式,不仅提升了执行效率,还增强了代码的组织性和可读性。掌握其使用,对于涉及文本分析、数据清洗、日志处理等领域的Python开发者来说,是非常必要的技能。正确并高效地应用这一功能,可以显著提升程序的性能和维护性。
145 0
|
3月前
|
索引 Python
30天拿下Python之正则表达式
30天拿下Python之正则表达式
20 0
|
3月前
|
数据采集 Python
Python正则表达式提取车牌号
Python正则表达式提取车牌号
49 0