0%

正则表达式-学习笔记

From 洛谷日报

正则表达式(Regular Expression, 简写为regex)

选择

|:或运算,选择(最低优先级)。

数量限定

+:前面的字符至少出现一次;

?:最多出现一次;

*:出现任意次(包括0次)。

括号

定义范围和优先度。

PCRE表达式

^:匹配输入字符串的开始位置。

$:匹配输入字符串的结束位置。

.:匹配除\r,\n之外任何单个字符。

{n}:匹配确定的n次。

{n,}:至少匹配n次。

{n,m}:最少n次最多m次。

?:非贪心量化:当该字符在任何其他重复修饰符(*,+,?{n}{n,}{n,m})后面时,匹配模式是非贪婪的(默认为贪婪)。例如,对于字符串"oooo","o+?“将匹配单个"o”,而"o+“将匹配所有"o”。

image-20210830091053128

(?:pattern):难以叙述…例如:industr(?:y|ies)等价于industry|industries。也就是说,如果pattern没匹配上,那么前面的字符也不匹配。

(?=pattern):正向肯定预查。Windows(?=95|98|NT|2000)能匹配Windows2000中的Windows,但不能匹配Windows3.1中的Windows。预查不消耗字符。

(?!pattern):正向否定预查。

(?<=pattern):反向肯定预查。(?<=95|98|NT|2000)Windows能匹配2000Windows中的Windows,但不能匹配3.1Windows中的Windows

(?<!pattern):反向否定预查。

[xyz]:匹配所包含的任意一个字符。

[^xyz]:匹配任意一个其他字符。

[x-z]:匹配范围内的任意一个字符。([^x-z]反之)

\b:匹配一个单词边界。

\B:匹配一个非单词边界。

\d:匹配一个数字。(\D反之)

\s:匹配一个空白字符。

\w:匹配任何单词字符(即字母、数字、下划线)。

POSIX字符组

[:alnum:]

[:alpha:]

[:ascii:]

[:lower:]

[:upper:]

优先级

优先权 符号
最高 \
()(?:)(?=)[]
*+?{n}{n,}{n,m}
^$、中介字符
次最低 串接,即相邻字符连接在一起
最低 |

Python应用

使用re库。

re.match(r'^\d{3}\-\d{3,8}$', '010-12345'),建议使用r前缀避免考虑Python的转义问题(正则的转义,如\-仍然要考虑)。re.match尝试从起始位置匹配一个模式。

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

re.search()扫描整个字符串并返回第一个成功的匹配。

findall()返回一个list,内容是所有匹配的子串(str)。

Match对象的方法:

  • start()返回匹配开始的位置
  • end()
  • span()返回(start(),end())

匹配邮件地址

re.match(r'^\w+(\w+|\.\w+)+@\w+(\w+|\.\w+)+$', addr)

切分字符串

'a b c'.split(' ')无法识别连续的空格。

re.split(r'\s+','a b c')可以。

分组

()表示要提取的分组。例如^(\d{3})-(\d{3,8})$定义了两个组。使用group()方法取出:

1
2
3
4
5
6
7
8
9
>>> m = re.match(r'^(\d{3})-(\d{3,8})$', '010-12345')
>>> m
<_sre.SRE_Match object; span=(0, 9), match='010-12345'>
>>> m.group(0) # 原串
'010-12345'
>>> m.group(1)
'010'
>>> m.group(2)
'12345'

命名分组

(?P<name>regex),调用:matchobj.group(name)

编译

每次使用正则表达式都需要编译,如果多次使用可以预编译:

1
2
3
4
5
6
import re
# 编译
re_telephone = re.compile(r'^(\d{3})-(\d{3,8})$')

>>> re_telephone.match('010-12345').groups()
('010', '12345')

替换

re.sub(pattern,repl,string)

repl是替换后的字符串,也可以是一个函数:这个函数传入的参数为Match对象。

假如文本有个单纯重复了 2 次,利用正则保留一个输出:

1
2
3
4
import re
x='this is is ok ok'
y= re.sub(r'(\w+)\s\1',r'\1',x)
print(y) # this is ok