元字符
常见正则表达式符号
符号 | 描述 | 示例 |
---|---|---|
literal | 匹配文本字符串的字面值literal | py |
re1|re2 | 匹配 re1 或 re2 | foo|bar |
. | 匹配任意字符(除\n) | py.n |
^ | 匹配字符串起始部分 | ^Dear |
$ | 匹配字符串终止部分 | .*.jpg$ |
* | 匹配0次或多次前面的模式 | [A-Za-z0-9]* |
+ | 匹配1次或多次前面的模式 | [a-z]+.com |
? | 匹配0次或1次前面的模式 | goo? |
{N} | 匹配N次前面的模式 | [0-9]{3} |
{M,N} | 匹配M~N次前面的模式 | [0-9]{5,9} |
[…] | 匹配来自字符集的任意单一字符 | [aeiou] |
[…x-y..] | 匹配x-y范围中的任意单一字符 | [A-Za-z] |
[^…] | 不匹配此字符集出现的任何单一字符 | [^aeiou],[^A-Za-z] |
(*|+|?|{})? | 匹配重复模式的非贪婪版本(*、+、?、{}为重复模式) | .*?[a-z] |
(…) | 匹配封闭的模式,然后另存为子组 | ([0-9]{3}?) |
常用特殊字符
符号 | 描述 | 示例 |
---|---|---|
\d | 匹配任何十进制数字,等价于[0-9],\D与之相反 | data\d+.txt |
\w | 匹配任何字母数字字符,等价于[A-Za-z0-9],\W与之相反 | word\w+.txt |
\s | 匹配任何空格字符,\S与之相反 | of\sthe |
\b | 匹配任何单词边界,\B与之相反 | \bThe\b |
\c | 匹配任何特殊字符(转义) | ., \, * |
\A(\Z) | 匹配字符串的起始(结束) | \ADear |
1)贪婪/非贪婪版本
正则表达式默认会进行贪婪匹配,即在多钟长度的匹配字符串中选择较长的哪一个
re.findall('py*','pyyyy')
-> ['pyyyy']
re.findall('py{2,}', 'pyyyy')
-> ['pyyyy']
re.findall('py{1,3}', 'pyyyy')
-> ['pyyy']
在不定次数的正则表达式后添加一个?就表示非贪婪匹配
re.findall('py*?','pyyyy')
-> ['p']
re.findall('py{2,}?', 'pyyyy')
-> ['pyy']
re.findall('py{1,3}?', 'pyyyy')
-> ['py']
2)捕获组
可以对正则表达式用()分组以方便索引
捕获组有 普通捕获组 和 命名捕获组 两种
# 普通捕获组
# 以数字为编号规则
p=re.compile('(a(b)c)d')
m=p.match('abcd')
m.group(0)
-> 'abcd'
m.group(1)
-> 'abc'
m.group(2)
-> 'b'
m.groups()
-> ('abc', 'b')
# 命名捕获组
# 对每个组显式命名以方便索引
# 形式:(?P<name>...)
p=re.compile('(?P<year>\d{4})-(?P<date>\d{2})-(?P<day>\d\d)')
m=p.match('2018-01-15')
m.group('date')
-> 01
3)非捕获组
仅匹配,但不保存该分组
方便理解正则表达式层次
p=re.compile('(?:\d{4})-(?P<date>\d{2})-(?P<day>\d\d)')
m=p.match('2018-01-15')
m.groups()
-> ('01', '15')
Python中使用正则表达式
1)import re 模块
2)使用 match、serach、findall、finditer方法进行匹配
编译
允许不对模式做编译而直接匹配,但预编译可以带来性能的提升
import re
p = re.compile(pattern, flags=0)
# p.match
匹配
# match 按照 pattern 从 string 开始位置进行匹配
re.match(pattern, string, flags=0)
# search 按照 pattern 从 string 中任意位置进行匹配
re.search(pattern, string, flags=0)
# findall 按照 pattern 找到 string 中所有匹配,并返回列表
re.findall(pattern, string[, flags])
# finditer 与 findall 类似,但返回迭代器
re.finditer(pattern, string[, flags]
替换
# sub 按照 pattern 将 string 中的模式换成 repl,并可限定替换次数 count
# subn 返回替换数目
re.sub(pattern, repl, string, count=0)
total = re.subn(pattern, repl, string, count=0)
re.sub('[ae]', 'x', 'abcdef')
-> 'xbcdxf'
re.subn('[ae]', 'x', 'abcdef')
-> ('xbcdxf', 2)
分隔
# 按照 pattern 分隔 string
re.split(pattern, string, max=0)
flags
- re.I / re.IGNORECASE:不区分大小写
- re.M / re.MULTILINE:^和$分别匹配字符串中行的起始和结尾,而不是严格匹配整个字符串的起始和结尾
- re.S / re.DOTALL:点号能够匹配全部字符(否则会排除\n)