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
”。
(?: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 | match(r'^(\d{3})-(\d{3,8})$', '010-12345') m = re. |
命名分组
(?P<name>regex)
,调用:matchobj.group(name)
编译
每次使用正则表达式都需要编译,如果多次使用可以预编译:
1 | import re |
替换
re.sub(pattern,repl,string)
repl
是替换后的字符串,也可以是一个函数:这个函数传入的参数为Match
对象。
假如文本有个单纯重复了 2 次,利用正则保留一个输出:
1 | import re |