10-1 初识正则表达式
# 正则表达式
# JSON(XML)
什么是正则表达式?
正则表达式是一个特殊的字符串序列,一个字符串是否与我们所设定的这样的字符序列相匹配。
快速检索文本、实现一些替换文本操作
1.检查一串数字是否是电话号码
2.检测一个字符串是否符合email
3.把一个文本里指定的单词替换为另一个单词。
# Q1:检测下列字符串中是否含有Python?
a = 'c|c++|java|c#|python|iavascript'
print(a.index('python')>-1)#用Python的内置函数index,这是方法一
print('python'in a)#这种方法也可以。打印结果如图1
# 接下来看看如何用正则表达式检测Python是否在字符串a里?
import re #python提供了一个re模块,re模块里提供了好多方法供我们操作正则表达式
a = 'c|c++|java|c#|python|iavascript'
r = re.findall('python',a)#这两个参数第一个是要填入需要匹配的正则表达式,第二个是需要传入所在字符串
print(r)
# 打印结果如图2所示,是一个含有Python字符串的列表,返回的结果是常量字符串,看似毫无意义。正则表达式的
# 灵魂在于 规则 !!!! 这个例子的规则抽象性太弱。很明确的告诉你,在字符串里找Python
# 看看完整的代码
import re
a = 'c|c++|java|c#|python|iavascript'
r = re.findall('python',a)
if len(r) > 0:
print('字符串中含有Python') #打印结果如图3
else:
print('NO')
image
image
image
10-2 元字符与普通字符
# Q1:如何提取下列字符串中的所有的数字?
a = 'c0c++7java8c#9python6javascript'
# 看下列代码
import re
a = 'c0c++7java8c#9python6javascript'
r = re.findall('\d',a) #0~9这些阿拉伯数字的正则表达式抽象就是“\d”
print(r)
# 打印结果如图1
# 总结一下:10-1中的例子‘Python’是一个普通字符,‘\d’是一个元字符,他们既可以单独使用,也可以搭配使用
# 百度正则表达式会出现很多元字符,根据自己的业务需求决定总结要使用哪种元字符!
# Q2:如何提取下列字符串中的所有字母,将数字除掉?
a = 'c0c++7java8c#9python6javascript'
# 看下列代码
import re
a = 'c0c++7java8c#9python6javascript'
r = re.findall('\D',a) # “\D”就是将数字去除
print(r)
# 打印结果如图2
10-3 字符集
# 看看正则表达式的第一个模式:字符集
# 字符集
# Q1:找出字符串所给单词中,中间一个是c或者f的单词!!?
import re
s = 'abc,acc,adc,aec,afc,ahc'
r = re.findall('a[cf]c',s)#字符集使用中括号,把需要抽象的字符集写在中括号里面!!
# 中括号两边的字母起到定界的作用!中括号里面的表示或的关系!!!
print(r)#打印结果如图1
# Q2:找出字符串所给单词中,中间一个不是c不是f不是d的单词!!?
import re
s = 'abc,acc,adc,aec,afc,ahc'
r = re.findall('a[^cdf]c',s)#字符集使用中括号,里面的向上的小箭头表示取反的操作
print(r)#打印结果如图2
# Q3:找出字符串所给单词中,找出中间一个是从c到f的单词!!?
import re
s = 'abc,acc,adc,aec,afc,ahc'
r = re.findall('a[c-f]c',s)#这里如果写成r = re.findall('a[cdef]c',s)这也是正确的,两种表述都对!
print(r)#打印结果如图3
image
image
image
10-4 概括字符集
# 概括字符集
# 目前所学习的两个 \d \D
# \w 匹配的都是单词字符 \W表示非单词字符,如空格,\n \t \r都是非单词字符,用\W,在打印结果中都可以看到
# \s用来匹配空白字符如:\n \t \r (&除外不能匹配,&有别于\n \t \r的特殊字符) \S用来匹配非空白字符
#补充一点: . 匹配除换行符\n以外其他所有字符
# 看下列代码
import re
a = 'python1111java678php'
r = re.findall('[0-9]',a) # 表示的意思是\d,打印的都是数字
print(r)
import re
a = 'python1111java678php'
r = re.findall('[^0-9]',a) # 表示的意思是\D,打印的都是字母
print(r)
# 上述打印结果如图1
# Q1:在一个字符串中,想要匹配所有的数字和字母,怎么操作?
import re
a = 'python1111java678php'
r = re.findall('[\w]',a) # \w,打印的都是字母和数字
print(r)
# 打印结果如图2
# Q2:在一个字符串中,想要匹配所有的数字和字母,怎么操作?
import re
a = 'python1111java&678php'#在字符串中加入&,看看结果如何?
r = re.findall('[\w]',a) # \w,打印的都是字母和数字
print(r)
# 打印结果如图2,跟图2一样
# \w 表示单词字符,意义如下:
import re
a = 'python1111java&678php'
r = re.findall('[A-Za-z0-9_]',a) # \w 表示就是中括号里面的[A-Za-z0-9_]意思是:大小写a-z,数字0-9,还有下划线
print(r)
# 看看下面的例子
import re
a = 'python1111java&678php___'
r = re.findall('[A-Za-z0-9_]',a) #相当于 \w
print(r)
# 打印结果如图3 ,看到了下划线
# Q3:在一个字符串中,想要匹配所有的非数字和字母,怎么操作?
import re
a = 'python1111java&678php'#在字符串中加入&,看看结果如何?
r = re.findall('[\W]',a) # \W,打印的都是非字母和数字
print(r)
# 打印结果如图4
# Q4:在一个字符串中,想要匹配所有的空白字符,怎么操作?
import re
a = 'python111\t1java\n&678php\r'
r = re.findall('[\s]',a) # \s,打印的都是空白字符
print(r)
# 打印结果如图5
image
image
image
image
image
10-5 数量词
10-6 贪婪与非贪婪
#数量词
# Q1:在一个字符串中,想要匹配所有的字母,怎么操作?
import re
a = 'python1111java678php'
r = re.findall('[a-z]',a) # a-z打印所有的字母
print(r)
# 打印结果如图1
# Q2:在一个字符串中,想要匹配所有的完整的单词,怎么操作?
import re
a = 'python1111java678php'
r = re.findall('[a-z]{3}',a) # [a-z]{3}表示单词以3个一组出现
print(r)
# 打印结果如图2,结果2中都是3个一组,并不是完整的字母,怎么办?
# Q3:在一个字符串中,想要匹配所有的完整的单词,怎么操作?
import re
a = 'python1111java678php'
r = re.findall('[a-z]{3,6}',a) # [a-z]{3,6}表示单词出现的形式,最少以3个字母,最多以6个字母出现。字母乘以数量的形式。
print(r)
# 打印结果如图3,是我们想要的结果
# 贪婪与非贪婪
# 在Python中,默认的是贪婪的匹配方式。看个例子
import re
a = 'python1111java678php'
r = re.findall('[a-z]{3,6}',a)
print(r)
# 根据图3的打印结果,当匹配到3个字母的时候,输出也是正确的,只不过Python采用的贪婪的匹配方式,会尽量多的往下匹配
# 来看下非贪婪的匹配
import re
a = 'python1111java678php'
r = re.findall('[a-z]{3,6}?',a) #[a-z]{3,6}?加这个问号就表示非贪婪的匹配
print(r)
# 打印结果如图4,这种非贪婪的匹配方式,跟{3}的匹配方式相同!
image
image
image
image
10-7 匹配0次1次或者无限多次
# 数量词
# * 匹配*前面的字符0次或者无限多次
# + 匹配*前面的字符1次或者无限多次
# ? 匹配?前面的字符0次或者1次
import re
a = 'pytho0python1pythonn2'
r = re.findall('python*',a) # 用* ,匹配*前面的字符0次或者无限多次
print(r)
# 打印结果如图1
# + 匹配*前面的字符1次或者无限多次
import re
a = 'pytho0python1pythonn2'
r = re.findall('python+',a) # 用+ ,匹配+前面的字符1次或者无限多次
print(r)
# 打印结果如图2
# ? 匹配?前面的字符0次或者1次
import re
a = 'pytho0python1pythonn2'
r = re.findall('python?',a) # 用? ,匹配?前面的字符0次或者1次
print(r)
# 打印结果如图3 ,打印第三个Python的时候,虽然是pythonn,但是打印出来的仍然是Python,
# 只是匹配了0次或者1次,多余的n都会被略去
# 在和贪婪与非贪婪中的?相比较的时候,贪婪与非贪婪出现的是范围,加问号表示非贪婪
# 这里表示:匹配?前面的字符0次或者1次
# 看看下面三段代码的意义和结果
import re
a = 'pytho0python1pythonn2'
r = re.findall('python?',a) # 用? ,匹配?前面的字符0次或者1次
print(r)
import re
a = 'pytho0python1pythonn2'
r = re.findall('python{1,2}?',a) # 用python{1,2}?表示非贪婪
print(r)
import re
a = 'pytho0python1pythonn2'
r = re.findall('python{1,2}',a) # 用python{1,2}表示贪婪
print(r)
# 打印结果如图4,三段代码的结果截然不同,意义不一样
image
image
image
image
10-8 边界匹配符
# 边界匹配
# Q1:怎么判断一个QQ号码在4~8位之间?
import re
a = '100001'
r = re.findall('\d{4,8}',a)#用此种方法可以判断出来
print(r)
# 打印结果如图1
# Q2:怎么判断一个QQ号码在4~8位之间?
import re
a = '101'
r = re.findall('\d{4,8}',a)#用此种方法可以判断出来
print(r)
# 打印结果如图2
# Q3:怎么判断一个QQ号码在4~8位之间?
import re
a = '100000001'
r = re.findall('\d{4,8}',a)#用此种方法可以判断出来
print(r)
# 打印结果如图3
# Q4:如何完全匹配一个QQ号码?要用到边界匹配了,如果一个QQ号码在4-8位之间,下面能匹配吗?
import re
a = '100000001'
r = re.findall('^\d{4,8}$',a)#用^\d{4,8}$前面加上^,表示从开始匹配,后面加上一个$,代表从后面开始匹配。一前一后表示完全匹配这个字符串
print(r)
# 打印结果如图4,结果是空的列表。无法匹配4-8的号码
# 看看下列代码,深入理解边界匹配!
import re
a = '100000001'
r = re.findall('000',a)#用此种方法可以判断出来
print(r)
# 打印结果如图5,两组000
import re
qq = '100000001'
r = re.findall('^000',a)#在000前面加一个向上的^
print(r)
# 打印结果是空列表,因为从开始匹配的数字是1,不是0,所以打印的是空列表
import re
qq = '100000001'
r = re.findall('000$',a)#在000的后面加上一个$
print(r)
# 打印结果是空列表,因为从末尾开始匹配的三个字母必须是000,但是目前的001,所以不匹配!所以打印的是空列表
10-9 组
# 组的概念 一个小括号就代表一个组
# Q1:判断一个字符串里是否包含3个Python?!
import re
a = 'pythonpythonpythonpythonpython'
r = re.findall('pythonpythonpython',a)#这种方法是可行的
print(r)
# 打印结果如图1
# 看看方法二
import re
a = 'pythonpythonpythonpythonpython'
r = re.findall('(python){3}',a)#(python),加上(),代表就是一个组,()里的内容是且的关系,【】里的是或的关系
print(r)
image
10-10 匹配模式参数
# 10-10 匹配模式参数
import re
lanuage = 'pythonC#javaphp'
r = re.findall('c#',lanuage)#将小写的c#看看打印出来的是啥?
print(r)
# 打印结果如图1,是一个空列表,因为区分大小写
# 那么有没有一种方法可以忽略大小写呢?看看下面的例子
import re
lanuage = 'pythonC#javaphp'
r = re.findall('c#',lanuage,re.I)#第三个参数就是flags,就是指的就是匹配模式
print(r)
# 打印结果如图2,打印出来了
# 第三个参数里面的re.I可以忽略大小写
# 还有一个就是re.S,匹配所有字符包括换行符!!!
# 看例子
import re
lanuage = 'pythonC#\njavaphp'
r = re.findall('c#.{1}',lanuage,re.I)#c#.{1}表示首先匹配c#任意的一个字符,包括换行符
print(r)
# 这样什么都打印不出来。正确的结果如下图
import re
lanuage = 'pythonC#\njavaphp'
r = re.findall('c#.{1}',lanuage,re.I | re.S)#c#.{1}表示首先匹配c#任意的一个字符,包括换行符,re.S,匹配所有字符包括换行符!!!
print(r)
# 打印结果如图3
# re.I | re.S(这是且的关系,既要忽略大小写,又要支持对点号行为的改变,两个同时满足,若果有需要,可以加竖线然后后面接着写)
image
image
image
10-11 re.sub正则替换
# 10-11 re.sub正则替换
# 正则表达式中,并不是仅仅只有re一个模块,本章介绍re.sub
# 看例子
# re.findall用于查找,今天所讲的re.sub用于替换
import re
lanuage = 'pythonC#javaphp'
r = re.sub('C#','GO',lanuage)#注意re.sub的几个参数的意义
print(r)
# 打印结果如图1
import re
lanuage = 'pythonC#javaC#phpC#'
r = re.sub('C#','GO',lanuage,0)#注意re.sub的0的意义表示无限制的匹配下去,不管多少C#,全部都会被替换
print(r)
# 打印结果如图2
import re
lanuage = 'pythonC#javaC#phpC#'
r = re.sub('C#','GO',lanuage,1)#注意re.sub的1的意义表示只有字符串中第一个C#会被替换
print(r)
# 打印结果如图3
# 看看下面的替换方法
import re
lanuage = 'pythonC#javaC#phpC#'
lanuage.replace('C#','GO')
print(lanuage)
# 打印结果如图4,发现并没有实现替换!原因是字符串是不可变得,lanuage.replace('C#','GO')需要接收一下变量
# lanuage = lanuage.replace('C#','GO')即可
# re.sub强大的地方是第二个参数可以是个函数:看下面例子
import re
lanuage = 'pythonC#javaC#phpC#'
def convert(value):
pass
r = re.sub('C#',convert,lanuage)
print(r)
# 打印结果如图5,C#消失不见了,是因为被函数里的空字符串替代了
# 继续看例子
import re
lanuage = 'pythonC#javaC#phpC#'
def convert(value):
return '!!' + value + '!!'
r = re.sub('C#',convert,lanuage)
print(r)
# 打印结果如图6,出现了报错,下面分析一下报错的原因:
import re
lanuage = 'pythonC#javaC#phpC#'
def convert(value):#字符串并不会直接传到convert里面
print(value)
#return '!!' + value + '!!'
r = re.sub('C#',convert,lanuage)
print(r)
# 打印结果如图7
# 看看正确的代码:
import re
lanuage = 'pythonC#javaC#phpC#'
def convert(value):#字符串并不会直接传到convert里面
matched = value.group()#拿到匹配结果
return '!!' + matched + '!!'
r = re.sub('C#',convert,lanuage)
print(r)
# 打印结果如图8,成功打印
image
image
image
image
image
image
image
image
10-12 把函数作为参数传递
# 10-12 把函数作为参数传递
# Q1:有一个字符串,找出里面所有的数字,凡是大于6的,全部替换成9,凡是小于6的,全部替换成0
import re
s = 'A8C3721D86'
def convert(value):
matched = value.group()
if matched >=6:
return 9
else:
return 0
r = re.sub('\d',convert,s)#首先拿到数字
print(r)
# 打印结果如图1,是报错的
# 正确的如下:
import re
s = 'A8C3721D86'
def convert(value):
matched = value.group()
if int(matched) >=6:
return '9'
else:
return '0'
r = re.sub('\d',convert,s)#首先拿到数字
print(r)
# 打印结果如图2,正确的
image
image
10-13 search与match函数
# 10-13 search与match函数
# findall search match,参数都是一样的,来看看match和search之间的不同
import re
s = 'A8C3721D86'
r = re.match('\d',s)
print(r)
# 打印结果如图1,没有匹配到结果
# 看看search
import re
s = 'A8C3721D86'
r = re.search('\d',s)
print(r)
# 打印结果如图2,匹配到一个结果
# 导致返回结果不同的原因是:match是从首字母匹配的,search是全部搜索型的!!!,若将字符串第一个字母去掉
# 他们的输出结果是一样的
# 拿到返回结果
import re
s = '8C3721D86'
r = re.search('\d',s)
print(r.group())
# 打印结果如图3
import re
s = '8C3721D86'
r = re.match('\d',s)
print(r.span())#返回结果的位置
# 打印结果如图4
# findall会将所有的数字都打印出,这就是三者的不同点!
image
image
image
image
10-14 group分组
# 10-14 group分组
# Q1:下面的字符串,如何提取life和Python之间的字母?
import re
s = 'life is short ,i use python'
r = re.search('(life.*python)',s)#点和星号的作用10-4中有讲
print(r.group())#group的意义在于获得一个分组的匹配,group里面的一个分组0,可以省略!!
# group(0)是一个特殊的匹配结果,返回的都是完整的结果
# 打印结果如图1
import re
s = 'life is short ,i use python'
r = re.search('life(.*)python',s)
print(r.group(1))#group填写1,从1开始接收返回结果
# 打印结果如图2
#看看search和findall之间进行比较
import re
s = 'life is short ,i use python'
r = re.findall('life(.*)python',s)
print(r)
# 打印结果如图3
# 看看多个分组的情况!!!!
# Q2:下面的字符串,如何提取life和Python以及Python和Python之间的字母?
import re
s = 'life is short ,i use python,i love python'
r = re.search('life(.*)python(.*)python',s)
print(r.group(0))#group填写0
print(r.group(1))#group填写1
print(r.group(2))#group填写2
# 打印结果如图4
# 上述情况和下面的是一样的
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))
# 打印结果如图5
# 看看groups的情况吧
import re
s = 'life is short ,i use python,i love python'
r = re.search('life(.*)python(.*)python',s)
print(r.groups())#groups不会返回完整的结果,只会返回要匹配的中间结果!也就是括号括起来的结果
# 打印结果如图6
image
image
image
image
image
image
0-15 一些关于学习正则的建议
10-16 理解JSON
什么是JSON?
JavaScript Object Notation
JavaScript对象标记
JSON:是一种轻量级的数据交换格式
易于阅读
易于解析
网络传输效率高
跨语言交换数据
10-17 反序列化
# 10-17 反序列化
# Q1:把已知的字符串转换成我们熟悉的Python字符串?(这个过程叫做反序列化)
import json
json_str = '{"name":"xiaoyu","age":18}' #json格式要求字符串必须加双引号
student = json.loads(json_str)
print(type(student))
print(student)
# 打印结果如图1所示,是字典的形式
import json
json_str = '{"name":"xiaoyu","age":18}'
student = json.loads(json_str)
print(type(student))
print(student)
print(student['name'])
print(student['age'])#通过这种访问方式可以非访问json中,我们想要的结果
# 打印结果如图2所示
# json的数据格式类型是对象形式,转换成Python里的字典数据类型
# json的数据格式类型是数组形式,转换成Python里的什么数据类型???看代码!!(答案是列表类型)
import json
json_str = '[{"name":"xiaoyu","age":18},{"name":"xiaoyu","age":18}]' #json的数组类型
student = json.loads(json_str)
print(type(student))
print(student)
# 打印结果如图3 4所示,是列表的形式
#还有bool类型的情况
import json
json_str = '[{"name":"xiaoyu","age":18,"flag":false},{"name":"xiaoyu","age":18}]' #json的数组类型
student = json.loads(json_str)
print(type(student))
print(student)
# 打印结果如图5,结果是大写的false
# json有自己的数据类型,我们用json.loads函数把json数据类型转换成我们所需要的类型。这个过程叫做反序列化
10-18 序列化
# 10-18 序列化
# 左边是json格式类型对应到右边的Python格式类型
json python
object dict
array list
string str
number int
number float
true True
false False
null None
# 看看序列化的过程,就是把Python的数据类型转换成json的数据类型
# Q1:把Python中的字典类型转换成json里的形式?
import json
student = [
{'name':'xiaoyu','age':18,'flag':False},
{'name':'xiaoyu','age':18}
]
json_str = json.dumps(student)#json.dumps序列化的过程
print(type(json_str))
print(json_str)
# 打印结果如图1,就是json格式
image
10-19 小谈JSON、JSON对象与JSON字符串
10-19 小谈JSON、JSON对象与JSON字符串
JSON:数据交换格式
JSON对象
image image作者:buaishengqi
链接:https://www.jianshu.com/p/dd37dc147f4a
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
网友评论