Python 正则表达式

举报
jcLee95 发表于 2023/06/08 21:47:06 2023/06/08
【摘要】 Python 正则表达式 李俊才的个人博客 邮箱 :291148484@163.com CSDN 主页:https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343 本文地址:https://blog.csdn.net/qq_28550263/article/details/123482797相关文章推荐:JavaScript 正则表达式...
Python 正则表达式

李俊才的个人博客
邮箱 :291148484@163.com
CSDN 主页https://blog.csdn.net/qq_28550263?spm=1001.2101.3001.5343
本文地址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 分组

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

import re

s = '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. 小例子

import re

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. 小例子

import re

re.match(
    r'mr_\w+',               # pattern
    'HELLO_EORLD hello_world',       # string
    re.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. 小例子

import re

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. 小例子

import re

re.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. 小例子

import re
re.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. 小例子

import re

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标准库:

import re

re.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标准库:

import re

print(re.escape('https://www.python.org'))  # https://www\.python\.org

legal_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()
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。