正则表达式
是什么
正则表达式(Regular Expression)目的是为了字符串模式匹配,从而实现搜索和替换功能。所以它是一种用来描述规则的表达式。
字符
既然字符串是为了字符串的模式匹配
所以组成
- 字符
 - 元字符
 
字符就是数字、英文字母。而元字符就是特殊字符,可以表示特殊语义的字符。
我们所要做的就是利用元字符构造强大的表达式
单个字符
#在apple中匹配ple
print(re.findall("p","apple"))
> ['p']
\转义字符
| 特殊字符 | 正则表达式 | 记忆方式 | 
|---|---|---|
| 换行符 | \n | new line | 
| 换页符 | \f | form feed | 
| 回车符 | \r | return | 
| 空白符 | \s | space | 
| 制表符 | \t | tab | 
| 垂直制表符 | \v | vertical tab | 
| 回退符 | [\b] | backspace,之所以使用[]符号是避免和\b重复 | 
多个字符
单个字符的映射关系是一对一的,即正则表达式的被用来筛选匹配的字符只有一个。而这显然是不够的,只要引入集合区间和通配符的方式就可以实现一对多的匹配了
#匹配1 2 3三个字符
 print(re.findall("[123]","[123456]"))
 > ['1', '2', '3']
-表示区间范围
print(re.findall("[1-3]","[123456]"))
> ['1', '2', '3']
利用-表示区间范围,所以[0-9]就能匹配所有数字 [a-z] 就能匹配所有小写字母
| 匹配区间 | 正则表达式 | 
|---|---|
| 除了换行符之外的任何字符 | . | 
| 单个数字, [0-9] | \d | 
| 除了[0-9] | \D | 
| 包括下划线在内的单个字符,[A-Za-z0-9_] | \w | 
| 非单字字符 | \W | 
| 匹配空白字符,包括空格、制表符、换页符和换行符 | \s | 
| 匹配非空白字符 | \S | 
循环与重复
如何同时匹配多个字符。要实现多个字符的匹配我们只要多次循环,重复使用我们的之前的正则规则就可以了
分类
- 0次
 - 1次
 - 多次
 - 执行次
 
?代表匹配一个或0个
* 代表匹配0个或无数个
+ 表示匹配1次或多次
{ } 表示匹配指定次数
- {n} n次
 - {min,max} 介于
 - {min,}至少min次
 - {0,max}至多max次
 
import re
#0~9的数字匹配三个
str = "a123456789"
print(re.search('[0-9]{3}',str)) #返回对象
<re.Match object; span=(1, 4), match='123'>
# 返回数字
str = "abc1s5df92f"
re.findall("[0-9]",str)
['1', '5', '9', '2']
# 从头匹配直到看到2
re.search('.*2','1a2bcc')
> 1a2
边界
在长文本字符串查找过程中,我们常常需要限制查询的位置。比如我只想在单词的开头结尾查找
单词边界
单词是构成句子和文章的基本单位,一个常见的使用场景是把文章或句子中的特定单词找出来。
re.findall("cat","more cat cat catkk")
> ['cat', 'cat', 'cat']
/b匹配单词边界
它匹配一个单词的边界
re.findall( r'\bbc\b' , "abc bc abbbc bcd" )
> ['bc']
re.findall( r'bc\b' , "abc bc abbbc bcd" )
> ['bc', 'bc', 'bc']
/B匹配非边界
#匹配包含bc但不以bc开头的 和以bc结尾的  
re.findall( r'\Bbc\b' , "abc bc abbbc bcd" )
> ['bc', 'bc']
字符串边界
^ 表示字符串的开头
$ 表示字符串的结尾
#匹配以he开头的
re.findall("^he","he is hello ")
> ['he']
分组
import re
data = "tashi123ale"
res = re.search('([a-z]*)([0-9]*)([a-z]*)',data)
print(res.groups())
print(res.group(1))
#身份证验证
data = "140830199810040017"
res = re.search('(?P<province>\d{3})(?P<city>\d{3})(?P<year>\d{4})',data)
print(res.groups())
print(res.groupdict()) #转变字典
('tashi', '123', 'ale')
tashi
('140', '830', '1998')
{'province': '140', 'city': '830', 'year': '1998'}
匹配分割
import re
data = "小红,小明,小花"
res = re.split(',',data)
print(res)
['小红', '小明', '小花']
匹配替换
参数1 匹配规则
参数2 要替换的字符
参数3 替换的数据
参数4 替换几个
import re
# help(re)
data = "小红,小明,小花"
res = re.sub(',','__',data,count=1)
print(res)
小红__小明,小花
总结
| 正则表达式 | 代表的匹配字符 | 
|---|---|
| . | 代表任意字符 | 
| \ | 逻辑或操作符 | 
| [ ] | 匹配内部的任一字符或子表达式 | 
| [^] | 对字符集和取非 | 
| - | 定义一个区间 | 
| * | 匹配前面的字符或者子表达式0次或多次 | 
| *? | 惰性匹配上一个 | 
| + | 匹配前一个字符或子表达式一次或多次 | 
| ? | 匹配前一个字符或子表达式0次或1次重复 | 
| {n} | 匹配前一个字符或子表达式 | 
| ^ | 匹配字符串的开头 | 
| \A | 匹配字符串开头 | 
| $ | 匹配字符串结束 | 
| \d | 单个数字0-9 | 
| \D | 除了0-9 | 
| \w | 单个字符a-z A-Z 0-9 | 
| \W | 除了[A-Za-z0-9] | 
| \s | 匹配空白字符,包括空格、制表符、换页符和换行符 | 
| \S | 匹配非空白字符 | 
Python
- re.match() 从头开始匹配,找到返回
 - re.search() 全局匹配包含
 re.findall() 搜索字符串,以列表形式返回全部能匹配的子串
re.split() 以匹配到的字符当作列表分隔符
- re.sub() 匹配字符并替换
 - re.fullmatch()全部匹配
 
标识符
- re.I 忽略大小写
 - re.S 改变.的行为
 - re.M 多行模式
 - re.X 给表达式写注释
 
Demo
# 请写出一个正则来处理数字千分位,如12345替换为12,345
import re
str = "12345"
re.findall("(\d{0,})(\d{3})",str)