一、正则表达式定义
正则表达式(regular expression): 就是用一个“字符串”来描述一个特征,然后去验证另一个“字符串”是否符合这个特征
例如: 表达式"ab+"
描述的特征是一个 'a'
和 任意个 'b'
,那么 'ab', 'abb', 'abbbbbbbbbb' 都符合这个特征。
正则表达式的作用
- 验证字符串是否符合指定特征,比如验证是否是合法的邮件地址。
- 用来查找字符串,从一个长的文本中查找符合指定特征的字符串,比查找固定字符串更加灵活方便。
- 用来替换,比普通的替换更强大。
二、正则表达式规则
2.1 普通字符
字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。
表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。
例如: 在字符串"abcde"
中匹配"bcd"
, "bcd"
里面的均是普通的字符.
2.2 简单转义字符
些不便书写的字符,采用在前面加 "\"
的方法.
表达式 | 可匹配 |
---|---|
\r , \n |
回车, 换行符 |
\t |
制表符 |
'\\' |
代表 "\" 本身 |
还有其他一些在后边章节中有特殊用处的标点符号,在前面加 "" 后,就代表该符号本身。比如:^, $ 都有特殊意义,如果要想匹配字符串中 "^" 和 "$" 字符,则表达式就需要写成 "^" 和 "$"。
表达式 | 可匹配 |
---|---|
'\^' |
匹配^ 符号本身 |
'\$' |
匹配$ 符号本身 |
'\.' |
匹配. 符号本身 |
这些转义字符的匹配方法与 "普通字符" 是类似的。也是匹配与之相同的一个字符
例如: 表达式"\$c"
匹配到, "ab$cd"
中匹配"$"
2.3 能够与 '多种字符' 匹配的表达式
正则表达式中的一些表示方法,可以匹配 '多种字符' 其中的任意一个字符
表达式 | 可匹配 |
---|---|
'\d' |
匹配 0~9 中任意一个数字 |
'\D' |
匹配任何一个非数字字符 |
'\w' |
任意一个字母或数字或下划线,也就是 A~Z ,a~z ,0~9 ,_ 中任意一个 |
'\W' |
匹配任何一个字母、数字、下划线以外的字符 |
'.' |
匹配除了换行符(\n )以外的任意一个字符 |
例如:
- 表达式
"\d\d"
,在匹配"abc123"
时, 匹配到的内容是:"12"
- 表达式
"a.\d"
,在匹配"aaa100"
时, 匹配到的内容是:"aa1"
2.4 自定义能够匹配 '多种字符' 的表达式
使用方括号 [ ]
包含一系列字符,能够匹配其中任意一个字符。用 [^ ]
包含一系列字符,则能够匹配其中字符之外的任意一个字符
表达式 | 可匹配 |
---|---|
'[ab5@]' |
匹配 "a" 或 "b" 或 "5" 或 "@"一个字符 |
'[^ab5@]' |
匹配 "a" 或 "b" 或 "5" 或 "@"以外的一个字符 |
'[f-k]' |
匹配 "f"~"k" 之间的任意一个字母 |
'[^A-F0-3]' |
匹配 "A""F","0""3" 之外的任意一个字符 |
例如
- 表达式
"[bcd][bcd]"
匹配"abc123"
时, 匹配到的内容是:"bc" - 表达式 "[^abc]" 匹配 "abc123" 时, 匹配到的内容是:"1"
2.5 修饰匹配次数的特殊符号
前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。比如:"[bcd][bcd]" 可以写成 "[bcd]{2}"。
表达式 | 作用 |
---|---|
'{n}' |
表达式重复n次 |
'{m,n}' |
表达式至少重复m次,最多重复n次 |
'{m,}' |
表达式至少重复m次 |
'?' |
匹配表达式0次或者1次 |
'+' |
表达式至少出现1次 |
'*' |
表达式不出现或出现任意次 |
例如
- 表达式
"\d+\.?\d*"
在匹配"It costs $12.5"
时, 匹配到的内容是:"12.5"
- 表达式
"go{2,8}gle"
在匹配"Ads by goooooogle"
时, 匹配到的内容是:"goooooogle"
2.6 抽象意义的特殊符号
一些符号在表达式中代表抽象的特殊意义
表达式 | 作用 |
---|---|
'^' |
字符串开始的地方匹配,不匹配任何字符 |
'$' |
字符串结束的地方匹配,不匹配任何字符 |
\b |
匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符 |
例如
- 表达式 "^aaa" 在匹配 "xxx aaa xxx" 时, 匹配失败, 只有当 "aaa" 位于字符串的开头的时候,"^aaa" 才能匹配
- 表达式 "aaa\(" 在匹配 "xxx aaa xxx" 时, 匹配失败, 只有当 "aaa" 位于字符串的结尾的时候,"aaa\)" 才能匹配
- 表达式 ".\b." 在匹配 "@@@abc" 时, 匹配成功;匹配到的内容是:"@a";
- 表达式 "\bend\b" 在匹配 "weekend,endfor,end" 时, 匹配成功;匹配到的内容是:"end"
一些符号可以影响表达式内部的子表达式之间的关系
表达式 | 作用 |
---|---|
'|' |
左右两边表达式之间 "或" 关系,匹配左边或者右边 |
'()' |
1. 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰 2. 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到 |
例如
- 表达式 "Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时,匹配成功;匹配到的内容是:"Tom";匹配下一个时,匹配结果是:成功;匹配到的内容是:"Jack"
- 表达式 "(go\s*)+" 在匹配 "Let's go go go!" 时,匹配成功;匹配到内容是:"go go go"
- 表达式 "¥(\d+.?\d*)" 在匹配 "$10.9,¥20.5" 时,匹配成功;匹配到的内容是:"¥20.5"。单独获取括号范围匹配到的内容是:"20.5"
2.7 分组
使用()
进行分组
- 分组命名
(?P
,xx) xx
为要匹配的表达式
2.8 注释
(?# xxx)
, xxx
为备注释的内容
更改多内容参见python官方文档
三、python正则表达式使用
python中内置模块re
提供了对正则表达式语法解析的支持
3.1 re模块 常用方法
-
re.compile(pattern, flags=0)
: 将正则表达式的样式编译为一个 正则表达式对象(正则对象)参数描述
参数 描述 pattern
匹配的正则表达式 flags
标志位,用于控制正则表达式的匹配方式 flags
flags 描述 re.A
或re.ASCII
让 \w
,\W
,\b
,\B
,\d
,\D
,\s
和\S
只匹配ASCII,而不是Unicodere.DEBUG
示编译时的debug信息,没有内联标记 re.I
或re.IGNORECASE
进行忽略大小写匹配;表达式如 [A-Z] 也会匹配小写字符 re.M
或re.MULTILINE
设置以后,1. 样式字符 '^'
匹配字符串的开始,和每一行的开始(换行符后面紧跟的符号)
2. 样式字符 '$' 匹配字符串尾,和每一行的结尾(换行符前面那个符号)re.S
或re.DOTALL
让 '.' 特殊字符匹配任何字符,包括换行符 re.X
或re.VERBOSE
该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。 -
re.search(pattern, string, flags=0)
: 扫描整个字符串找到匹配样式的第一个位置,并返回一个相应的 匹配对象。如果没有匹配,就返回一个None
-
re.match(pattern, string, flags=0)
: 如果string
开始的0或者多个字符匹配到了正则表达式样式,就返回一个相应的 匹配对象 。 如果没有匹配,就返回None
-
re.fullmatch(pattern, string, flags=0)
: 如果整个string
匹配到正则表达式样式,就返回一个相应的匹配对象。否则就返回一个None
-
re.split(pattern, string, maxsplit=0, flags=0)
: 用pattern
分开string
。 如果在pattern
中捕获到括号,那么所有的组里的文字也会包含在列表里。如果maxsplit
非零, 最多进maxsplit
次分隔, 剩下的字符全部返回到列表的最后一个元素 -
re.findall(pattern, string, flags=0)
: 对string
返回一个不重复的pattern
的匹配列表,string
从左到右进行扫描,匹配按找到的顺序返回。如果样式里存在一到多个组,就返回一个组合列表;就是一个元组的列表(如果样式里有超过一个组合的话)。空匹配也会包含在结果里。 -
re.finditer(pattern, string, flags=0)
:pattern
在string
里所有的非重复匹配,返回为一个迭代器iterator
保存了匹配对象。 string 从左到右扫描,匹配按顺序排列。空匹配也包含在结果里。 -
re.sub(pattern, repl, string, count=0, flags=0)
: 替换字符串中的匹配项, 如果样式没有找到,则不加改变地返回string
参数 描述 pattern
匹配的正则表达式 repl
替换的字符串,也可为一个函数 string
要被查找替换的原始字符串 count
替换次数 -
re.subn(pattern, repl, string, count=0, flags=0)
: 行为与sub()
相同,但是返回一个元组(字符串, 替换次数)
. -
re.escape(pattern)
: 转义pattern
中的特殊字符 -
re.purge()
: 清除正则表达式的缓存
示例
import re
pattern_str = r"(\d+\.?\d*)"
string = "It costs $12.5"
print(re.search(pattern_str, string))
print(re.match(pattern_str, string))
print(re.split(pattern_str, string))
print(re.findall(pattern_str, string))
print(re.finditer(pattern_str, string))
print(re.sub(pattern_str, "25.5", string, count=1))
3.2 正则表达式对象(正则对象)方法
-
Pattern.search(string[, pos[, endpos]])
: 扫描整个string
寻找第一个匹配的位置, 并返回一个相应的匹配对象。如果没有匹配,就返回None
参数 描述 pos
字符串中开始搜索的位置索引, 默认0 endpos
限定了字符串搜索的结束索引 -
Pattern.match(string[, pos[, endpos]])
: 如果string
的开始位置能够找到这个正则样式的任意个匹配,就返回一个相应的匹配对象。如果不匹配,就返回None
-
Pattern.fullmatch(string[, pos[, endpos]])
: 如果整个string
匹配这个正则表达式,就返回一个相应的匹配对象。 否则就返回None
-
Pattern.split(string, maxsplit=0)
: 等价于re.split()
函数 -
Pattern.findall(string[, pos[, endpos]])
: 类似函数re.findall()
, 可以接收可选参数pos
和endpos
,限制搜索范围 -
Pattern.finditer(string[, pos[, endpos]])
: 类似函数re.finiter()
, 可以接收可选参数 pos 和 endpos ,限制搜索范围 -
Pattern.sub(repl, string, count=0)
: 等价于re.sub()
函数 -
Pattern.subn(repl, string, count=0)
: 等价于re.subn()
函数
示例
import re
pattern = re.compile(r"(\d+\.?\d*)")
print(pattern.search("It costs $12.5")) # search() 便利整个字符串
print(pattern.match("It costs $12.5")) # match() 字符串开始位置搜索
print(pattern.findall("It costs $12.5")) # findall() 将匹配到的分组存放在列表中
print(pattern.finditer("It costs $12.5")) # finditer() 将匹配成功的匹配对象放在生成器中
print(pattern.sub("25.5", "It costs $12.5", count=1)) # sub()替换匹配到地内容
print(pattern.fullmatch("12.5")) # fullmatch() 整个字符串匹配成功
3.3 匹配对象(Match)
-
Match.expand(template)
: 对template
进行反斜杠转义替换并且返回 -
Match.group([group1, ...])
: 返回一个或者多个匹配的子组, 触发Match.__getitem(g)
方法 -
Match.groups(default=None)
: 返回一个元组,包含所有匹配的子组,在样式中出现的从1到任意多的组合 -
Match.groupdict(default=None)
: 返回一个字典,包含了所有的 命名 子组。key就是组名
import re
pattern_str = r"(?P\d+\.?\d*)"
string = "It costs $12.5"
match = re.search(pattern_str, string)
print(match.groupdict())
print(match.group(1))
print(match.groups())