python基础汇总(四)

今天我们来讲一讲正则表达式与json,这些知识将涉及到WEB开发和爬虫开发等等一系列项目。

我在学习的过程中,发现一个不错的网站,也是一个比较知名的网站,就是菜鸟教程:http://www.runoob.com

这个网站的知识点汇总还是很齐全的。

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。能快速检索文本,实现一些替换文本的操作。

使用的时候,需要引用re模块,re 模块使 Python 语言拥有全部的正则表达式功能。

一.re.findall

re.findall功能:在字符串中找到正则表达式所匹配的所有子串,并返回一个列表,如果没有找到匹配的,则返回空列表。

例子如下:

import re

a='one3# 6\two@8 _three ^go'

b=re.findall('two',a)   #匹配指定的字符串,输出结果是['two']

c=re.findall('d',a)      #匹配任意的数字,输出结果是['3', '6', '8']

d=re.findall('D',a)     #匹配任意非数字,包括空白,输出结果是['o', 'n', 'e', '#', ' ', '\', 't', 'w', 'o', '@', ' ', '_', 't', 'h', 'r', 'e', 'e', ' ', '^', 'g', 'o']

e=re.findall('w',a)     #匹配数字和字母以及下划线,输出结果是['o', 'n', 'e', '3', '6', 't', 'w', 'o', '8', '_', 't', 'h', 'r', 'e', 'e', 'g', 'o']

f=re.findall('W',a)     #匹配非(字母数字下划线),包括空白,输出结果是['#', ' ', '\', '@', ' ', ' ', '^']

g=re,findall('s',a)      #匹配空白符号,包括相关制表符,输出结果是[' ', ' ', ' ']

h=re.findall('S',a)     #匹配非(空白符号,相关制表符),输出结果是['o', 'n', 'e', '3', '#', '6', '\', 't', 'w', 'o', '@', '8', '_', 't', 'h', 'r', 'e', 'e', '^', 'g', 'o']

print(b)

print(c)

print(d)

print(e)

print(f)

print(g)

print(h)

输出结果:

['two']

['3', '6', '8']

['o', 'n', 'e', '#', ' ', '\', 't', 'w', 'o', '@', ' ', '_', 't', 'h', 'r', 'e', 'e', ' ', '^', 'g', 'o']

['o', 'n', 'e', '3', '6', 't', 'w', 'o', '8', '_', 't', 'h', 'r', 'e', 'e', 'g', 'o']

['#', ' ', '\', '@', ' ', ' ', '^']

[' ', ' ', ' ']

['o', 'n', 'e', '3', '#', '6', '\', 't', 'w', 'o', '@', '8', '_', 't', 'h', 'r', 'e', 'e', '^', 'g', 'o']

我们在这段程序中介绍了常见的其中匹配模式,我们可以总结出规律,同种字母的大小写,匹配的模式对立的;大小写对应的匹配模式如果并集,是等同于一个完整的原字符串。

那么。下面将会介绍更多的常见匹配模式:

import re

a='6A5e*8W-y09udpOc7wD'

b=re.findall('[a-z]',a)              #匹配a到z的小写字母,输出结果是:['e', 'y', 'u', 'd', 'p', 'c', 'w']

c=re.findall('[A-Z]',a)              #匹配A到Z的大写字母,输出结果是:['A', 'W', 'O', 'D']

d=re.findall('[0-9]',a)               #匹配0到9的所有数字,输出结果是:['6', '5', '8', '0', '9', '7']

e=re.findall('[A-Za-z0-9]',a)    #匹配所有数字和大小写字母,输出结果是:['6', 'A', '5', 'e', '8', 'W', 'y', '0', '9', 'u', 'd', 'p', 'O', 'c', '7', 'w', 'D']

f=re.findall('[^abcde]',a)          #匹配除了abcde小写字母以外所有的字符,输出结果是:['6', 'A', '5', '*', '8', 'W', '-', 'y', '0', '9', 'u', '$', 'p', 'O', '7', 'w', 'D']

g=re.findall('[^A-Z]',a)             #匹配除了A到Z所有大写字母以外的所有字符,输出结果是:['6', '5', 'e', '*', '8', '-', 'y', '0', '9', 'u', 'd', '$', 'p', 'c', '7', 'w']

print(b)

print(c)

print(d)

print(e)

print(f)

print(g)

输出结果:

['e', 'y', 'u', 'd', 'p', 'c', 'w']

['A', 'W', 'O', 'D']

['6', '5', '8', '0', '9', '7']

['6', 'A', '5', 'e', '8', 'W', 'y', '0', '9', 'u', 'd', 'p', 'O', 'c', '7', 'w', 'D']

['6', 'A', '5', '*', '8', 'W', '-', 'y', '0', '9', 'u', '$', 'p', 'O', '7', 'w', 'D']

['6', '5', 'e', '*', '8', '-', 'y', '0', '9', 'u', 'd', '$', 'p', 'c', '7', 'w']

那么这些就是更多常见的匹配模式,千万要避免这些错误的写法: ’^abcde‘   ,  '^[A-Z]'   等等。

接下来,我将拓展更多的匹配模式……

面对一个乱七八糟的字符串,你想从中提取有效的信息,比如指定长度:

import re

a=‘sett3oi23oisyudga2isydhjb2siygk%sos2*sjjbdjb'

#可能这段字符看起来非常糟糕,但可以尝试索取一下你认为最可能的信息

b=re.findall('[a-z]{1,3}',a)  #匹配a到z字母中的长度在1到3之间的字符串

print(b)

输出结果是:

['set', 't', 'oi', 'ois', 'yud', 'ga', 'isy', 'dhj', 'b', 'siy', 'gk', 'sos', 'sjj', 'bdj', 'b']   #里面有一个sos求救信号。

细心的你发现了吗,你发现了一个sos的字符串,这个很明显是你要提取的求救信息。

当然,有些初心的入学者,会不注意大小写的匹配情况:

import re

a=’Java、C#|C++#PYThon‘

b=re.findall('python',a)

print(b)

去尝试运行,却发现报错,报错内容竟是找不到匹配的相应字符串。

是因为大小写并不一样,原字符串中是’PYThon‘,前面三个字母是大写的,自然是匹配不出来的。

所以后面需要加一个修饰符re.I,使匹配对大小写不敏感:

import re

a='Java、C#|C++#PYThon'

b=re.findall('python',a,re.I)

print(b)

输出结果:

['PYThon']    #不要陷入误区,输出结果并不会是['python'],输出结果是字符串里面匹配出来的。

我们会经常碰到重复字符串,我们同样也需要提取处理,比如‘fuc09fuckk7efuck28s’,但是我们可以发现,如果直接进行对‘fuck’提取处理,会提取出好几个类似的‘fuc’,‘fuckk’等,这样会很耗时。

这就涉及到贪婪匹配和非贪婪匹配模式的知识点:

 *    将有关的字符全部打印出来,包括正确,少打,多打的情况。

 +   将有关的字符打印出来,只包括正确,多打的情况。

 ?  将有关的字符打印出来,包括少打,正确的情况,对多打的情况匹配正确的情况。

首先先确定目标字符串‘fuck’,然后选择一种匹配模式,加在字符串后面,最后进行匹配处理。

我们来应用到代码之中:

import re

a='fuc09fuckk7efuck28s'

b=re.findall('fuck*',a)   #提取正确,少打,多打的字符串,输出结果是:['fuc', 'fuckk', 'fuck']

c=re.findall('fuck+',a)   #提取正确,多打的字符串,输出结果是:['fuckk', 'fuck']

d=re.findall('fuck?',a)   #提取正确,少打的字符串,对多打的字符串提取正确的字符串。输出结果是:['fuc', 'fuck', 'fuck']

print(b)

print(c)

print(d)

输出结果:

['fuc', 'fuckk', 'fuck']

['fuckk', 'fuck']

['fuc', 'fuck', 'fuck']

二.re.sub

re.sub用于替换字符串中的匹配项,是对字符串的指定部分进行正则替换操作的函数。公式如下:

re.sub(pattern, repl, string, count=0, flags=0)

pattern是字符串中要更换的部分,repl是更换的内容,string是原始字符串。

count是需要更换的次数,按顺序更换。其中,count=0是默认替换全部,而不是替换0个。

flags是可选的,表示匹配模式,比如忽略大小写,多行模式等

来看看一段简单的替换,助于理解:

a='fuckGOyouRISHME'

b=re.sub('GO','COME',a)

print(b)

输出结果:

fuckCOMEyouRISHME

很显然,其中的GO替换成COME了。当然了,千万不要犯错误,比如输入‘go’替换,这样会报错大小写不匹配噢。

解决的方法当然是使这个过程不对大小写敏感,后面加一个修饰符re.I就行:b=re.sub('go','COME',a,re.I)

等等,难道你们没有发现我这段代码不对劲吗,还有我写的东西也不对劲吗?

没发现,直接运行,会直接报错吗?很显然,我上面这段话,犯了两个错误:

①编写代码的时候,永远都不要忘了你要引用re功能的时候,开头加一句import re,否则就不能使用re.sub的功能。

②读文章的时候,记得要养成动手的习惯,也要记住我说过的东西。

我在上面就写了re.sub的公式:re.sub(pattern, repl, string, count=0, flags=0),请问我按照公式严格写了吗?

所以b=re.sub(‘go’,'COME',a,re.I)是错误的写法,因为python会把re.I误识别为count的部分,而并非是flags部分。

正确的写法是:b=re.sub(‘go’,'COME',a,0,re.I)

不要相信我上面写的输出结果是多少,这个世界上只有你亲自打印出来的输出结果是正确的。

永远保持动手能力和一颗质疑的心,亲自敲出来的代码才是正确的代码。

所以,纠正一下上面的一大段话,正确的代码如下:

import re

a='fuckGOyouRISHME'

b=re.sub('GO','COME',a)

c=re.sub('go','COME',a,0,re.I)    #匹配不受大小写影响。

print(b)

print(c)

输出结果:

fuckCOMEyouRISHME

fuckCOMEyouRISHME

注意,re.sub一定要严格按照公式编写,如果要用到后面修饰符的功能,count部分需要写个0。

接下来我们看看这个公式中count部分的应用吧!

import re

a='fuckGOyouGORISHGOME'

b=re.sub('GO','66',a,0)

c=re.sub('GO','66',a,2)

print(b)

print(c)

输出结果:

fuck66you66RISH66ME     #count=0是指默认全部替换,而不是替换0个。

fuck66you66RISHGOME   #count=2,按顺序替换前面两个GO 。

来看看对这一段程序执行的功能的白话解释:当字符串中想要更换的部分存在多个,可以后面再添加一个参数,控制更换的数量,按顺序。

输出结果中,count=0很显然并不是一般意义上的0个,而是默认全部替换。当count=2时,会按顺序替换前面两个

当然了,re.sub的花样并不是只有这么多,还可以进行一个删除的操作,那就是将替换的部分替换成无,不就是变相删除吗?

import re

a='fuckGOyouGORISHGOME'

b=re.sub('GO',' ',a)

print(b)

输出结果:

fuckyouRISHME

当然了,玩花活是可以的,可以将这一段函数复杂化:

import re

a='fuckGOyouGORISHGOME'

def convert1(value):

    pass

b=re.sub('GO',convert1,a)

print(b)

输出结果:

fuckyouRISHME

所以可以看到,公式里的repl部分是可以用函数操作的。

这段函数的意思就是,在re.sub的替换操作之下,对GO进行convert1函数的pass操作,也就是换成无,也就是删除。

所以,这一段的作用就是去掉所有GO。

当然了,除了替换无之外,还能替换添加字符的操作,比如将GO替换成666GO666,传统方法可以直接做到,但在此介绍用函数的方法替换:

import re

a='fuckGOyouGORISHGOME'

def convert2(value):

    matched=value.group()    #将同时匹配到的三个’GO‘字符进行分组有序化,防止python不知道先处理哪一个而出错。

    return '666'+ matched +'666'

b=re.sub('GO',convert2,a)

c=re.sub('GO',convert2,a,2)

print(b)

print(c)

输出结果:

fuck666GO666you666GO666RISH666GO666ME

fuck666GO666you666GO666RISHGOME

这段函数的意思就是,在re.sub的替换操作之下,将GO替换成666GO666。

那么,为什么要对value进行group()操作呢,不能直接return吗?value本身不就是字符串吗?

原因啊,其实很简单,在匹配GO字符串出来的时候,其实是有三个GO被同时匹配出来,直接替换会被报错,python不知道怎么按顺序。

所以,建立一个matched变量,将value变量里面匹配出来的三个GO进行分组操作,让它有序。

注意,return的时候,要用str数据类型去返回,这样就是字符串替换字符串的正确过程。

c变量的作用很好猜,自然是只替换前两次的GO。

当然了,re,sub还能和if条件语句一起完成替换的过程:

import re

a='AKH8787AS67F67SF6A89'

def convert3(value):

    matched=value.group()      

    if int(matched) > 7:          #注意,匹配出来的数字是str数据类型。

        return '0'

    else:

        return '1'

b=re.sub('d',convert3,a)     #将d匹配出来的数字进行函数convert3的处理。

print(b)

输出结果:

AKH0101AS11F11SF1A00

这一段就是一个数字替换的函数,首先d匹配出所有的数字,然后按照函数内容来更换,得到最后的结果。

注意,这次我犯了个错误,return后面的0和1我都没有打上srt引号,导致报错。

要知道,value匹配'd'的结果是str类型的数字,然后经过group()分组处理得出的matched变量还是str类型

所以更换数字要同样的str类型去return。

以上就是re.sub的一些常见替换用法。

三.re.matched和re.search

re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

re.search 扫描整个字符串并返回第一个成功的匹配

a='life is short,i use python.'

b=re.search('life.*python',k)

print(b)

print(b.group())

首先,打印出输出结果

<re.Match object; span=(0, 26), match='life is short,i use python'>

life is short,i use python

我们可以看到,第一条打印的是程序运行的过程,并不是用户想要看到的最终输出。

于是第二条进行分组化,将匹配出来的字符串包装,进行打印。

life. 是以life开头往后匹配;*python,是pytho前所有的都匹配出来。两者都包含本身。

那么两者有什么不同之处呢?

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

那么以上这些就是python中的正则表达式,那么如何赋予应用呢,我们来看看JSON吧。

什么是JSON?

英文全名:JavaScript Object Notation

中文翻译:  Javascript对象标记

JSON是一种轻量级的数据交换格式,易于人阅读和编写,网络传输效率高。

记住,JSON是一种数据形式,JSON的表现形式是字符串。

凡符合JSON格式的字符串就叫做JSON字符串。

JSON的作用很强大,可以完成跨语言交换数据的功能。

比如现有不同的A语言和B语言,若想要进行转换,中间的桥自然就是JSON数据形式。

那么如果要使用JSON函数,还是一如既往的引用库:import json

那么这方面我们只需要了解两个函数:

①json.loads

作用:用于解码JSON数据,返回Python数据类型。

import json

json_thing='{"name":"666","age":"18"}'    #定义一个json类型变量。

python_thing=json.loads(json_thing)      #解码JSON数据,转为python数据。
print(python_thing)
print(type(python_thing))          #查看转换后的变量类型,是否为python数据类型,输出结果是<class 'dict'>。
print(type(json_thing))
输出结果:

{'name': '666', 'age': '18'}
<class 'dict'>
<class 'str'>

②json.dumps

作用:用于将Python对象编码成JSON字符串。

import json

python_thing={"name":"666","age":"18"}

json_thing=json.dumps(python_thing)
print(json_thing)
print(type(json_thing))                      #我们可以看到输出结果,虽然转换后的形式没变,但是数据类型变了。
print(type(python_thing))

输出结果:

{"name": "666", "age": "18"}                #注意,虽然转换后的结果跟转换前的结果一样,但是数据类型变了。
<class 'str'>                                        #我们可以发现,看上去像是字典的形式,实际上已经成了JSON的str类型。
<class 'dict'>

经过上面两段程序,相比大家已经对JSON有了一定的了解,能理解JSON数据类型与python数据类型之间的转换过程。

那么我们来看看更多的转换数据类型。

时刻清楚这一点,JSON是一种数据类型,以str形式展现。

原文地址:https://www.cnblogs.com/Masterpaopao/p/10061575.html