八、正则表达式与Json

8 正则表达式与Json

8.1 正则表达式

正则表达式是一个特殊的字符序列,它能检测一个字符串是否与我们所设定的字符序列相匹配;
正则表达式由一系列普通字符和元字符(如’\d’等)组成;
它能实现快速检索文本、一些替换文本的操作;
正则表达式最重要的是在于规则.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#元字符(概括字符集)
r3 = re.findall('\d',ss)
r33 = re.findall('[0-9]',ss)
print('r33 : ' )
print(r33)
print(r3)
r4 = re.findall('\D',ss)
print(r4)

#字符集
s2 = 'adf,akj,dlok,aoiyf,acf,asf'

#在正则表达式中,普通字符常用于定界
re1 = re.findall('a[dc]f',s2)
#正则表示式的中括号[]内的字符是 或 关系
print(re1)
# ^ 表示相反的操作
re2 = re.findall('a[^dc]f',s2)
print(re2)

a. 数量词

1
2
3
4
5
6
#数量词
#数量词 [a-z]{3} 用来匹配长度为3的小写字母字符
# [a-z]{3,6} 匹配长度3-6的小写字母字符
s4 = 'python phpjva3python\t-=7phpaAkbjava'
re4 = re.findall('[a-z]{3,6}',s4)
print(re4)

b. 常见的概括字符集:
\d:0-9的数字,等价于[0-9]
\D: 非数字,等价于[^0-9]
\w:匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的”单词”字符使用Unicode字符集。
\W:匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\s:匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]
\S:匹配任何可见字符。等价于[^ \f\n\r\t\v]
. 匹配除换行符(\n)以外的所有字符

1
2
3
4
5
6
7
8
9
10
11
12
# 概括字符集
# \d [0-9] \D
# 单词字符 \w [A-Za-z0-9_] \W
# \s 空白字符 \S 非空白字符
# . 匹配除换行符(\n)以外的所有字符
s3 = 'sj@0-=56ljjg_l*jlkfmmm e\npl\tfef\rlkf#'
rs3 = re.findall('\w',s3)
print(rs3)
rs4 = re.findall('\s',s3)
print(rs4)
res55 = re.findall('.',s3)
print(res55)

c. python在进行正则表达式匹配时倾向于贪婪。在匹配字符串时若在结尾加上?则可进行非贪婪匹配

1
2
3
# ? 非贪婪,python一般默认是贪婪模式匹配
re5 = re.findall('[a-z]{3,6}?',s4)
print(re5)

d.(1) * 匹配它前面的字符0次或无限多次
(2) + 匹配它前面的字符1次或无限多次
(3) ? 匹配它前面的字符0次或1次
注:若?前是字符出现次数范围则代表非贪婪。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
ssd = 'pytho5python1pythonn787pithon1pythonnnn'
# * 表示 n 要出现 0 次或者无限多次
re6 = re.findall('python*',ssd)
print(re6)

# + 表示 n 要匹配1次或者无限多次
re7 = re.findall('python+',ssd)
print(re7)

# ?(前边没有次数范围的情况下) 表示 n 要匹配0次或者1次
re8 = re.findall('python?',ssd)
print(re8)

# 贪婪
re9 = re.findall('python{1,3}',ssd)
print(re9)
# 加 ? 变为非贪婪
re91 = re.findall('python{1,3}?',ssd)
print(re91)

8.2 边界匹配符

1
2
3
4
5
6
7
8
9
10
import re
# 边界匹配
qq = '123456'
# ^ 表示从开始边界开始匹配,$ 表示从结尾边界开始匹配
# {,} 表示区间; [-] 表示范围
res = re.findall('^\d{4,6}$',qq)
# 两个等价,对比一下[-]与{,}之间的区别
res1 = re.findall('^[0-9]{4,9}$',qq)
print(res)
print(res1)

8.3 组、匹配模式参数、re.sub

8.3.1 匹配中的组
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import re
# 组:用()将一些字符括起来,作为一个整体来匹配
# []里边的字符是 或 关系,()里边的字符是 且 关系
ss = 'javad3phpphpphp98gf7phpjavaphp803kitty'
# 匹配出3个php
s1 = re.findall('(php){1,5}?',ss)
print(s1) #s1 = ['php', 'php', 'php', 'php', 'php']
s2 = re.findall('(php){1,5}',ss)
print(s2) #s2 = ['php', 'php', 'php']
s3 = re.findall('(php){3}',ss)
print(s3) # s3 = ['php']
a = "PythonPythonPythonPythonPython"
r = re.findall("(Python){3}",a)#表示Python以组的形式匹配 连续出现3次才算匹配成功
# r = ['Python']
print(r)
8.3.2 匹配模式参数

常用匹配模式:
re.I 让正则表达式忽略大小写,这样一来,[A-Z]也可以匹配小写字母了;
re.S 影响’.’的行为,平时’.’匹配除换行符以外的所有字符,指定了本标志以后,也可以匹配换行符.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
import re
#匹配模式参数
s = 'hdjHs$\nttt'
# re.I表示匹配时忽略大小写
s1 = re.findall('hs$',s,re.I)
print(s1) #很奇怪,匹配结果为空

ss = 'hdjHs$\nttt'
s2 = re.findall('hs',ss,re.I)
print(s2) # ['Hs'] 结果正常

# .匹配除换行符以外的其他字符
# re.S 表示匹配所有字符;多个re. 之间 用 | 相关联
ss1 = 'hdjHs\nttt'
s3 = re.findall('hs.{2}',ss1,re.I | re.S)
print(s3)

8.3.3 re.sub 正则替换(把函数当作参数来传递)

re模块下常用函数:
findAll查找函数;
sub查找并替换(简单的字符串替换可以用字符串内置函数,如str.replace);
注:使用sub进行正则替换时可以传入函数来进行替换(可以根据不同匹配的结果替换成不同的目标字符串),如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import re
#re.sub替换
ais = 'CatdogdogHorseAntSheepdog'
#默认替换all
ais2 = re.sub('dog','water',ais,count=0)
print(ais2) # CatwaterwaterHorseAntSheepwater
# 设置只替换一次
ais3 = re.sub('dog','water',ais,count=1)
print(ais3)#CatwaterdogHorseAntSheepdog
# 简单的替换可以用replace, 默认是替换all
ais4 = ais.replace('dog','water',1)
print(ais4) # CatwaterDogHorseAntSheepdog
print('===============')

# 用于re.sub 替换的函数
def convert(vaules):
#vaules会是一个对象,通过group取其值
vaule = vaules.group()
# print(vaule)
# print(type(vaule))
vaule = int(vaule)
if vaule == 0:
return ' Ios:'
elif vaule == 1:
return ' Fit:'
elif vaule == 2:
return ' Healthy:'
elif vaule == 3:
return ' Friends:'
else:
return ' Who are you:'
snc = '0Apps1RunJoy2Keep3Wechat4Momo'
rsnc = re.sub('\d',convert,snc)
print(rsnc) #Ios:Apps Fit:RunJoy Healthy:Keep Friends:Wechat Who are you:Momo

8.4 serch与match函数、group分组

8.4.1 serch与match函数

re模块中函数:
match函数:从字符串首字母开始匹配,如首字母满足则返回,不满足,则直接结束;
search函数:搜索整个字符串,返回第一个匹配的结果;
注:这两个函数一旦匹配到结果就立即返回而不继续匹配,且二者返回的都是一个对象,而不像findall直接返回结果。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import re

ss = '2huh083h8j20l'
s1 = re.search('\d',ss)
print(s1) # <_sre.SRE_Match object; span=(0, 1), match='2'>
print(s1.span()) #匹配结果的位置信息: (0, 1)

s2 = re.match('\d',ss)
print(s2) # <_sre.SRE_Match object; span=(0, 1), match='2'>
print(s2.group()) #匹配到的值: 2

ss2 = 'sh39nnjl09lh7ek8'
r1 = re.search('\d',ss2)
print(r1)#<_sre.SRE_Match object; span=(2, 3), match='3'>

r2 = re.match('\d',ss2)
print(r2) # None

8.4.2 group分组

正则表达式中组的概念:
用括号括起来的多个字母,用于一次匹配一个字符串而不是单个字符。如果正则表达式中都是普通字符的话,默认是一个组;
在使用re模块中的search函数时,访问返回的匹配字符串时,可以使用group函数指定要访问的组,如:
import re
s = ‘life is short,i use python, i love python’
r = re.search(‘life(.)python(.)python’, s)
print(r.group(0, 1, 2))
注:若组号为0表示整个字符串。也可以使用groups函数以字符串元组形式返回所有匹配字符串。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import re

s = 'life is short,i use python;beautiful is -python'
rs1 = re.search('life(.*)python',s)
print(rs1)
# <_sre.SRE_Match object; span=(0, 47), match='life is short,i use python;beautiful is -python'>
print(rs1.group())
#life is short,i use python;beautiful is -python
print(rs1.group(1))
# is short,i use python;beautiful is -
rs2 = re.search('life(.*)(python){1}',s)
print(rs2.group())
#life is short,i use python;beautiful is -python
rs3 = re.search('life(.*)python(.*)python',s)
print(rs3.group(2))
#;beautiful is -
print(rs3.group(0,1,2))
#('life is short,i use python;beautiful is -python', ' is short,i use ', ';beautiful is -')

rs4 = re.findall('life(.*)python',s)
print(rs4)
#[' is short,i use python;beautiful is -']

8.5 Json、序列化及反序列化

8.5.1 Json

a. Json:一种轻量级的数据交换格式;字符串是其表现形式;
优点:易于阅读,易于解析、网络传输效率高;可用于跨语言交换数据
b. json_str=’{“name”:”小气”,”age”:18}’ #JSON 字符串
json_array=’[{“name”:”小气”,”age”:18},{“name”:”小气”,”age”:18}]’#JSON数组
里面 是双引号的话,外面必须是单引号
JSON格式的字符串键值必须是双引号,数字可以不加双引号;
json字符串loads,转换成dict字典;jsonarray数组loads,转换成列表;
JSON字符串到某种语言的解析过程叫反序列化.

反序列化:

1
2
3
4
5
6
7
8
9
10
11
12
13
import json
#反序列化
# json字符串里边用双引号,外边用单引号 json-true----python-True
s = '{"animals":"cat","name":"mini","age":1,"Flag":true}'
ps = json.loads(s)
print(type(ps)) # <class 'dict'>
print(ps) # {'animals': 'cat', 'name': 'mini', 'age': 1, 'Flag': True}

#json数组
ss = '[{"animals":"dog","name":"dahei"},{"animals":"cat","name":"mini"}]'
sp = json.loads(ss)
print(type(sp)) # <class 'list'>
print(sp) #[{'animals': 'dog', 'name': 'dahei'}, {'animals': 'cat', 'name': 'mini'}]

8.5.2 序列化(json.dumps)及反序列化(json.loads)

a.序列化:将python数据类型向json字符串转换的过程;
可以使用json模块中的dumps函数,将要转化的数据类型作为参数传入。
b.反序列化: 将json数据转换为其他类型的数据。
注意:序列化与反序列化并不局限与pyhon和json数据之间的转化。

序列化:

1
2
3
4
5
6
7
8
9
import json
#序列化
cat = [{'name':'mini','age':1},
{'name':'kitty','age':2,'Flag':True}]
# 将对象存储时可用:NOSQL,Mongo DB
s = json.dumps(cat)
print(type(s)) # <class 'str'>
print(s)
# [{"name": "mini", "age": 1}, {"name": "kitty", "age": 2, "Flag": true}]

josn与python对应数据类型列表:

8.6 Json对象、Json、Json字符串

注意对JSON的理解的误区:
a. 应该跳出特定语言的范畴来理解JSON. (JSON并不是专属于特定语言里的,如JavaScript)
JSON和JavaScript一样,是W3C标准script(ECMA Script)的实现方式之一。
b. 由于JS是目前主流的Web前端语言,而JSON被大量用于JavaScript的交互层, 因此常被误解为附属于JavaScript。
c. json对象:JSON本身没有对象的概念,通常这个问题是关联到javascript里时带出来的。
d. json: 有自己的数据类型(虽然和Javascript的数据类型有些类似)
json字符串:
e. JSON是REST服务的标准格式:
REST服务的标志性特点就是轻量,正好与JSON的特点相匹配,因此在REST服务中应该多采用JSON而不是XML。

分享到