目录
2020-2-1 21:08 星期六
正则表达式
- 正则表达式概述:
所谓正则表达式(Regula Expression)又称为正规表达式等等。主要的用途是用作字符串的匹配,在某些编辑器里用作检索替换某些文本。例如我们在linux中常用的 find *text就是一个正则表达式,相当于进行匹配带有text的所有的文本。
-
1. 在python中使用
import re #表示导入正则表达式的使用模块 result = re.match(正则表达式,要进行匹配的字符串) result.group() ''' def match(pattern, string, flags=0): """Try to apply the pattern at the start of the string, returning a Match object, or None if no match was found.""" return _compile(pattern, flags).match(string) 查看match方法的源码可以看到,如果正则表达式成立则返回一个匹配的对象(match object), 不成立则返回的是None。值得注意的是返回的是none表示空值,但并不是一个空格 '''
- 2. 单个字符串的匹配
-
. 同称表示占位符一样的东西
import re result1 = re.match(r".","\nuao") result2= re.match(r".","huao") print(result1) print(result2)
运行结果
result1返回的结果没有匹配到
result2返回的结果是匹配到了 h
可以看到 . 它是不可以对\n进行匹配的 -
\d 对[0-9]的数字进行匹配
-
\D 对非数字进行匹配
-
\s 对空格进行匹配
-
\S 对非空格进行匹配
-
\w 对[0-9],a-z,A-Z,_下划线都可以进行匹配
-
\W 对不是的单词字符进行匹配
用法和上面的一样。需要注意的是这个匹配的仅仅只能匹配第一个字符,不能匹配后面的字符。所以成为单个字符的匹配
-
- 3. 包含数量信息字符串的匹配
- []表示允许出现的字符的集合
- *表示可以出现0个或者无限个这样的字符(可有可无)
- +表示可以出现1个或者无限个这样的字符(可有不可无)
- ?表示可以出现0个或者1个这样的字符
- {m}表示该类字符后面有m个
- {m,}表示该类字符后面至少有m个(>=m)
- {m,n}表示该类字符后面至少有m到n个(m,n)
用法示例:
# []表示列举第一位的下一位能够出现的字符集合 # result = re.match("1[^3,4,5,6,7]",number) #表示除了第一位匹配1以外,第二位可以匹配的字符集为[3,4,5,6,7] .^这个符号表示取反 # print(re.match("1[3-9]",number)) # 3-9 表示连续的从3到9是连续的 # result = re.match("\d*","90909") #*表示这单个字符可以出现0次或者无数次,而不是数字,但是可以认为数字没有出现所以还是能够进行匹配(即可有可无) # result = re.match("\d+","00000") #+表示这单个字符可以出现1次或者无数次,,空格不行的原因是空格不是数字在这里就是没有数字出现所以返回none(即至少因该有一次) # result = re.match("\d?[a-z]","1234asf") #?表示这单个字符可以出现0次或者1次.即要么有一次要么没有. # result = re.match("\d{4}[a-z]","1234asf") #{}大括号里面写的数字表示匹配字符出现几次.前面的写的4表示字符应该出现4次 # result = re.match("\d{1,}[a-z]","1234asf") #{}这样表示匹配的字符最少应该出现n次,代码上写的一次,就相当于+号至少出现一次 # result = re.match("\d{1,4}[a-z]","1234asf") #{m,n}表示匹配的字符最少应该出现m到n次
- 4. 包含边界信息字符串的匹配
- ^ 表示必须以什么开头(这是在括号外面,再括号里面表示取反,一定要注意进行区别)
- $ 表示必须以什么结尾
- \b 表示以什么为结尾的单词边界
- \B 表示以非单词为结尾的边界
用法示例:边界信息 匹配手机号的方式(以什么开头和结尾的方式): result = re.match(r"1[35678]\d{9}$","130000000") #^表示以什么为开始.$表示以什么为结束 \b匹配一个单词的边界 \B匹配非单词的边界 result = re.match(r"\w+rd\b","heard") #rd\b表示以rd为结尾的单词边界 result = re.match(r"\w+%\B","hea%") #\B表示以%结尾的边界 result = re.match(r"\w+\s+\brd\b","hea rd") #\brd\b表是要么左边的空格右边是rd,要么右边是空格左边是rd.
- 5. 匹配分组
-
| 选择分组
-
() 将括号中的字符串作为一个分组
-
\num 将分组放置到mun位置
-
(?P) 给分组起名字便于后面进行应用
-
(?P=name) 应用分组
补充: 应用分组的主要目的是为了提取方便和提取自己想要的部分.这是分组提取的特点| (选择分组) 用法示例
# |表示匹配左右任意一个正则表达式 import re result1 = re.match("hu|ao","hu") result2 = re.match("hu|ao","ao") print(result1,result2)
运行截图
() (选择分组) 用法示例#()括号的作用起一个分组的作用 import re result1 = re.match("<h1>(.*)</h1>","<h1>huao</h1>") #表示两边的匹配格式固定,只对中间的()类的东西进行提取 result2 = re.match("(<h1>).*(</h1>)","<h1>huao</h1>") #对两边的进行提取 print(result1.group(1)) print(result2.group(1)) print(result2.group(2)) #括号内的参数实际上表示的是第几个括号内的内容
运行截图
(?P和(?P=name)这两个是一起的)(选择分组) 用法示例#()括号的作用起一个分组的作用 #初级版本 import re # 假设我们要对<html><h1>huao</h1></html> 这个标签进行匹配的话 result1 = re.match(r"<.+><.+>.+</.+></.+>","<html><h1>huao</h1></html>") #这样是可以进行匹配到的 result2 = re.match(r"<.+><.+>.+</.+></.+>","<html><h1>huao</h1></h2>") #这样是可以进行匹配到的,但是前后不一样也可以进行匹配 result3 = re.match(r"<(.+)><(.+)>.+</\2></\1>","<html><h1>huao</h1></h2>") #这样是可以进行匹配到的,但是前后不一样也可以进行匹配 result4 = re.match(r"<(.+)><(.+)>.+</\2></\1>","<html><h1>huao</h1></html>") #这样是可以进行匹配到的,但是前后不一样也可以进行匹配 print(result1.group()) print(result2.group()) print(result3) print(result4.group()) #但是当括号多了记起来就会非常的麻烦,所以就开始使用命名来进行修改,这样会便于进行使用 #升级版本 #分组起别名(?p<name>) 分组起别名 s1 = "<html><h1>huao</h1></html>" s2 = "<html><h1>huao</h1></h2>" result1 = re.match(r"<(?P<name1>.+)><(?P<name2>.+)>.+</(?P=name2)></(?P=name1)>",s1) result2 = re.match(r"<(?P<name1>.+)><(?P<name2>.+)>.+</(?P=name2)></(?P=name1)>",s2) print(result1) print(result2)
运行截图(初级版本)
运行截图(升级版本)
-
- 6.(groups,sub,findall,search,split)常用方法的讲解
-
groups
在前面已经见过了在这里就不再仔细的说了
用法示例:#groups的用法: str = "<html><h1>huao</h1></html>" result = re.match(r"<(.+)><(.+)>.+<(.+)><(.+)>",str) print(result.groups()) #说白了groups就是将分组一起放在一个元组中间
运行截图:
-
sub
sub是用做替换使用的,能将匹配的字符串中所有符合要求的进行替换成为自己所要替换的.可以使用自己写的方法进行规律的替换用法示例:
#sub的替换用法。 #格式sub(r"正则表达式","替换的内容或者使用替换的方法","进行匹配的字符串") r1 = "huhuaoaoaohuhuaoao" result = re.sub(r"hu","ao","huhuhuhuaoaoaaoaoao") print(result) #sub的方法替换用法 #写上一个方法进行指定的替换 def add(result): return str(int(result.group())+50) result = re.sub(r"\d+",add,"python =10,c=100") print(result)
替换用法运行截图:
方法用法运行截图:
-
search和findall要放在一起进行讲解便于理解记忆
serach 只要匹配到了就会停止,并不会将所有的符合要求的都列举出来
finedall 会将所有的符合要求的都列举出来用法示例:
# search和findall的用法 r1 = "<h2>hu</h1>huao</h1>huao</h2>" result = re.search(r"\w+</h1>",r1) result1 = re.findall(r"\w+</h1>",r1) print(result) print(result1)
运行截图:
-
split
在字符串中用过很多次就直接上代码
用法示例:#split的进行切割的算法 str = "我去。上/学=校背!着-炸-药=包一边走。一。边。笑我。说我。要。去。炸。学。校" result=re.split(r",|。|/|=|!|-",str) print(result)
运行截图:
-
- 7.贪婪模式和非贪婪模式的理解
- 贪婪和非贪婪其实上非常的好理解.给两个例子就能够明白了
用法示例:
运行截图:#贪婪模式的讲解 r = "aa2343ddd" result1 = re.match(r"aa\d+",r) result2 = re.match(r"aa\d+?",r) result3 = re.match(r"aa(\d+?)(\d+?)",r) result4 = re.match(r"aa\d+?ddd",r) print(result1.group()) print(result2.group()) print(result3.groups()) print(result4.group())
所谓贪婪顾名思义是在合理合法的范围内能多贪就多贪.字符串的匹配也是一样.
result1中的add后面只是限制了类型,并没有限制个数,自然所有的数字都会被匹配上
result2中加了中止贪婪模式的?表示要么有一个数字要么没有数字,所以最小限度的匹配了
result3中两个最小的限制自然是匹配的两个数字用groups的形式进行输出
result4中为什么可以都匹配上呢?因为在满足前面aa后面ddd的情况下,能多进行匹配就会多进行匹配.其实也是符合贪婪模式的
- 贪婪和非贪婪其实上非常的好理解.给两个例子就能够明白了