【Python】正则表达式与JSON
正则表达式
概述
定义
正则表达式是一个特殊的字符序列,可以检测一个字符串是否与我们设定的这样的字符序列相匹配
作用
快速检索文本、实现一些替换文本的操作
比如
- 检查一串数字是否为电话号码
- 检测一个字符串是否符合email
- 把一个文本里指定的单词替换为另一个单词
栗子
1 | a='C|C++|Java|C#|Python|Javascript' |
['Python'] # 返回一个列表
改写原代码
1 | import re |
正则表达式重要在规则(灵魂)上,而不是设置成常量(设置成‘Python’)
组成
正则表达式由一系列普通字符和元字符所组成
- 普通字符 (形如前面例子中的’Python’ )
- 元字符
- ‘\d’ 元字符(代表数字)
- ‘\D’ (代表非数字字符)
- ‘\w’(匹配数字和字母和下划线)
- ‘\W’ 匹配非单词字符(\r,\t,’ ‘)
- ‘\s’ 匹配空白字符(空格回车制表)
- . 匹配除换行符外所有字符
模式
字符集
[ ]中的字符集合
在[]中匹配“或”的关系
[afc]
在[]匹配取反操作
[^afc]
在[]中有顺序操作
[c-f] # 匹配cdef
概括字符集
- ‘\d’等价于[0-9]
- ‘\D’等价于[ ^0-9 ]
- ‘\w’等价于[A-Za-z0-9_]
只能匹配出单字符(以一个字符为单位的结果),因为元字符是字符存在
1 | import re |
['acc','afc']
数量词
假设在’pytho0python1pythonn2’串中寻找python
表示形式
{ } 前面单个字符的重复
r=re.findall('[a-z]{3}',a) # 数量词为3 r=re.findall('[a-z]{3,6}',a) # 支持范围,重复3-6次
*前面的字符(n)可以出现0次或者无限多次
r=re.findall('python*',a) # 表示一个重复的操作
+前面的字符可以出现一次或者无限多次
r=re.findall('python+',a) #
?前面的字符可以出现1次或者0次
r=re.findall('python?',a) # 去重操作
下面是’*’,’+’,’?’的例子
1 | import re |
['pytho','python','pythonn']
['python','pythonn']
['pytho','python','python']
贪婪与非贪婪
贪婪模式:努力寻找更多符合的条件
1 | import re |
['python', 'pythonn'] # 默认贪婪
['python', 'python'] # 非贪婪
?的”非贪婪限制”和”自身意义”区别
1 | import re |
['python','pythonn']
['python','python']
['pytho','python','python']
边界匹配
1 | import re |
^:从源字符串开始匹配
$:从源字符串末尾匹配
1 | import re |
[000,000] # 两组000
[] # 字符串开始匹配为非0,所以无匹配结果
组
1 | a='PythonPythonPythonPtyhonPython' |
()组:里面的字符为且关系,一个正则表达式中可以有多个组
[]字符集:里面字符为或关系
re.findall第三个参数
第三个参数代表 模式:
re.I 忽略第一个参数大小写
re.S .将匹配所有字符(包括换行符\n)
第三个参数中可以有多个模式 用|连接 表示 且 关系
re模块下的其他函数
re.sub()字符串替换
5个参数
- pattern:正则表达式(精准定位)
- 要替换成的新串
- 源串
- count参数:所能被替换最大次数(0默认为贪婪 全部替换)
强大部分:第二个参数可以是函数1
2
3
4
5
6import re
language='PythonC#JavaC#PHPC#'
def convert(value):
pass
r=re.sub('C#',convert,language)
print(r)
PythonJavaPHP # C#被全部删除
原理:
第一个正则表达式将作为传入第二个函数
函数返回的结果将作为第二个参数
1 | import re |
<re.Match object; span=(6, 8), match='C#'>
<re.Match object; span=(12, 14), match='C#'>
<re.Match object; span=(17, 19), match='C#'>
PythonJavaPHP
通过print(value)发现,C#被传入了value object(对象)进而传入函数sub中。
span表示C#在源串中的位置(第a个字符之后,第b个字符结束)
从value中对象拿出结果C#方法
matched=value.group() #用matched接收
1 | import re |
Python!!C#!!Java!!C#!!PHP!!C#!!
第二个函数为参数的意义:
根据不同结果进行不同的替换操作
比如:将’ABC3721D86串中的大于6的数字替换成9,小于等于6的数字替换成01
2
3
4
5
6
7
8
9
10import re
language='ABC3721D86'
def convert(value):
matched=value.group()
if int(matched)>6: # 传入函数的是字符
return '9'
else:
return '0' # 返回字符串的应该是字符串,不能直接返回int型数字
r=re.sub('\d',convert,language)
print(r)
ABC0900D90
输入函数的是一个字符串,return回来的也须是一个字符串
match()函数和search()函数
match():从源字符串首字母开始匹配,如果没有匹配,则返回None
search():搜索整个字符串,若找到第一个匹配字符串,返回一个对象。
如果要读取对象返回的结果
r.group()
如果要读取返回的位置
r.span()
match()和search()都只会匹配一次,findall()会找出所有匹配结果
group分组
提取字符串’life is short, i use python’中life和python之间的内容
1 | import re |
is short, i use
group():
- 可以传入一个参数,指定获取的组号,默认group(0)
- 若要访问内部分组,从group(1)开始
(group(0)属于特殊情况:永远记录正则表达式完整匹配结果) - 可同时访问多个组号
print(r.group.(0,1,2)) # 以元组形式返回
groups():
只会返回中间()匹配项
1 | import re |
('life is short, i use python, i love python', ' is short, i use ', ',i love ')
(' is short, i use ', ', i love ')