1, 匹配普通字符
'abc'
re.findall('abc','abcdefgabc')
2, 或 |
元字符: ab|bc
匹配规则:匹配2遍任意一个正则表达式
re.findall('ab|bc','abcdefgbc')
3, 元字符 .
匹配规则: 匹配除了换行之外的任意字符
>>> re.findall('f.o','foo is not fao or feo')
['foo', 'fao', 'feo']
4, 匹配开头位置: ^
匹配规则: 匹配一个字符串的开始
^Error
5, 匹配结束位置: $
.py$
6, 匹配重复,元字符 *
匹配规则: 匹配前面的正则表达式重复0次或多次
fo* --> foo f fooooooo
7, 匹配重复,元字符: +
匹配规则,匹配前面的正则表达式重复1次或多次
ab+ --> ab, abb, abbbbb
8, 匹配重复:?
规则: 匹配前面的正则表达式重复0次或1次
ab? --> a ab
9, 匹配重复 {n}
规则: 匹配指定的重复次数
ab{4} --> abbbb
10, 匹配规则:{m,n}
规则: 匹配前面的正则表达式重复m次到n次
ab{3,5} , abbb, abbbb, abbbbb
11, 匹配字符集合
元字符[]
规则: 匹配括号范围内任意一个字符
[a-z]
[A-Z]
[0-9]
[abc123]
[0-9a-zA-Z]
12, 匹配字符集合
元字符 [^...]
匹配除指定字符集之外的任意字符
[^A-Z]
13, 匹配任意(非)数字字符
元字符: \d \D
规则: \d匹配任意数字字符, \D 匹配任意非数字字符
等价于[0-9] [^0-9]
14, 匹配(非)普通字符, 数字字母下划线
元字符\w \W
匹配规则: \w 任意普通字符, \W 任意非普通字符
等价于 [_0-9a-zA-Z]
15, 匹配空字符 或 非空字符
元字符 \s \S
规则: \s 任意空字符, \S 任意非空字符
等价于 [ \n\r\t]
16, 匹配起止位置
元字符: \A \Z
规则: \A 匹配开始位置 \Z 匹配结束位置
用于绝对匹配;等同 ^ $
eg
匹配特定路径: 例如想从文本中匹配/export/data/mysql ,只匹配这个目录,不匹配其他;
re.findall('/\w+/\w+/\w+','/export/data/mysql/log')
re.findall('\A/\w+/\w+/\w+\Z','/export/data/mysql/log')
re.findall('\A/\w+/\w+/\w+\Z','/export/data/mysql abc') 等同
re.findall('^/\w+/\w+/\w+$','/export/data/mysql')
17, 匹配(非)单词边界
元字符: \b \B
规则: \b 匹配单词的边界, \B匹配非单词边界
单词边界: 数字字母下划线\w 和其他字符\W的交界位置为单词边界
r: 原始字符串,让转义功能失效
re.findall(r'is','This is a testing..') 匹配两个is
re.findall(r'\bis\b','This is a testing..') 匹配第二个is
re.findall(r'\bis\b','This is a testing..') 匹配第一个is
eg
re.findall('[A-Z]\w+','hello World, China. ###')
re.findall('[A-Z]\w+#*','hello World, China## ###')
练习:
匹配IP地址
s = "2019-01-03 15:44:56 18075 [Note] Server hostname (bind-address): '172.20.18.13'; port: 3358"
re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}',s)
匹配8-10位密码,必须以数字开头,数字字母下划线组成
re.findall(r'\b\d\w{7,9}\b','this is my password: 1Password ')
元字符总结:
匹配单个字符: a . \w \W \d \D \s \S [...] [^...]
匹配次数 * + ? {N} {n,m}
匹配位置: ^ $ \A \Z \b \B
其他: | () \
转义符:一些特殊符号具有特殊作用,并不是代表本身含义,如果需要表示本身含义,则需要转义
特殊含义发符号: . * ? + ^ $ '' "" [] {} () \
re.findall('\"\.\"','this is "." ')
r -- raw 原生字符串
s = r'\"\.\"'
贪婪和非贪婪
1, 正则表达式匹配的时候,会尽可能多的向后匹配;重复次数不确定时产生贪婪模式
* + {n,m} ?
>>> re.findall('ab*','abbbbbbbb')
['abbbbbbbb']
非贪婪模式: 尽可能少的匹配,满足正则表达式含义即可,多一点思考?
贪婪--> 非贪婪 *? +? ?? {n,m}?
正则表达式分组
使用() 可以为正则表达式建立一个子组,子组可以看做一个内部的整体
子组的作用
1, 增加子组后对正则表达式整体的匹配内容没有影响
2, 子组可以改变重复元祖字符的重复行为;
3, 子组在某些操作中可以对子组匹配内容进行单独提取
子组的注意事项
1,每个正则表达式可以有多个子组;由外到内,由左到右 为第一子组,第二子组...
2,如果正则表达式有子组的话,则只会显示子组匹配到的内容,而不会匹配整体所显示的内容。如果需要整体匹配的内容则在外围加个子组
捕获组和非捕获组(命名组和非命名组)
子组命名格式:
(?P<name>abc) name即该子组名字
重复调用:
(?P=name)
1, 为了编程方便,很多编程接口可以直接通过名字获取子组匹配内容
2, 捕获组中的正则表达式可以通过名字重复调用
(?P<dog>ab)cdef(?P=dog)