博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
正则表达式模块
阅读量:6608 次
发布时间:2019-06-24

本文共 11166 字,大约阅读时间需要 37 分钟。

什么是正则表达式

一组特殊符号组成的表达式,用于描述某种规则。该应用场景生活中随处可见。

例如:让有志青年过上体面的生活,这里面就由规则,即有志青年。

正则表达式的作用,以及使用场景

1.用于从字符串中匹配满足某种规则的内容,多数用于爬虫应用程序

2.判断字符串串内容是否满足某种规则,多用于严重用户输入。例如密码是否规范,手机号是否正确等

学习重点

正则是一堆特殊符号组成的,我们主要学习的就是这些特殊符号

 

元字符 描述
\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配\n。“\n”匹配换行符。序列“\”匹配“\”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
^ 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式任意次。例如,zo能匹配“z”,也能匹配“zo”以及“zoo”。等价于{0,}。
+ 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
{
n}
n是一个非负整数。匹配确定的n次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
{
n,}
n是一个非负整数。至少匹配n次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
{
n,m}
mn均为非负整数,其中n<=m。最少匹配n次且最多匹配m次。例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。
? 当该字符紧跟在任何一个其他限制符(,+,?,{
n},{
n,},{
n,m*})后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']
.点 匹配除“\n”和"\r"之外的任何单个字符。要匹配包括“\n”和"\r"在内的任何字符,请使用像“[\s\S]”的模式。
   
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[zf]ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“abc”可以匹配“plain”中的“plin”任一字符。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“a-z”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1”可以匹配“1_23”中的“1”,但不能匹配“21_3”中的“1_”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”
\s 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S 匹配任何可见字符。等价于 \f\n\r\t\v
\w 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
\W 匹配任何非单词字符。等价于“A-Za-z0-9_”。
\d 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
\D 匹配一个非数字字符。等价于0-9。grep要加上-P,perl正则支持
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\t 匹配一个制表符。等价于\x09和\cI。
( ) 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
(?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
| 将两个匹配条件进行逻辑“或”(Or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。

 

# =================================匹配模式=================================#一对一的匹配# 'hello'.replace(old,new)# 'hello'.find('pattern')#正则匹配import re#\w与\Wprint(re.findall('\w','hello egon 123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']print(re.findall('\W','hello egon 123')) #[' ', ' ']#\s与\Sprint(re.findall('\s','hello  egon  123')) #[' ', ' ', ' ', ' ']print(re.findall('\S','hello  egon  123')) #['h', 'e', 'l', 'l', 'o', 'e', 'g', 'o', 'n', '1', '2', '3']#\n \t都是空,都可以被\s匹配print(re.findall('\s','hello \n egon \t 123')) #[' ', '\n', ' ', ' ', '\t', ' ']#\n与\tprint(re.findall(r'\n','hello egon \n123')) #['\n']print(re.findall(r'\t','hello egon\t123')) #['\n']#\d与\Dprint(re.findall('\d','hello egon 123')) #['1', '2', '3']print(re.findall('\D','hello egon 123')) #['h', 'e', 'l', 'l', 'o', ' ', 'e', 'g', 'o', 'n', ' ']#\A与\Zprint(re.findall('\Ahe','hello egon 123')) #['he'],\A==>^print(re.findall('123\Z','hello egon 123')) #['he'],\Z==>$#^与$print(re.findall('^h','hello egon 123')) #['h']print(re.findall('3$','hello egon 123')) #['3']# 重复匹配:| . | * | ? | .* | .*? | + | {n,m} |#.print(re.findall('a.b','a1b')) #['a1b']print(re.findall('a.b','a1b a*b a b aaab')) #['a1b', 'a*b', 'a b', 'aab']print(re.findall('a.b','a\nb')) #[]print(re.findall('a.b','a\nb',re.S)) #['a\nb']print(re.findall('a.b','a\nb',re.DOTALL)) #['a\nb']同上一条意思一样#*print(re.findall('ab*','bbbbbbb')) #[]print(re.findall('ab*','a')) #['a']print(re.findall('ab*','abbbb')) #['abbbb']#?print(re.findall('ab?','a')) #['a']print(re.findall('ab?','abbb')) #['ab']#匹配所有包含小数在内的数字print(re.findall('\d+\.?\d*',"asdfasdf123as1.13dfa12adsf1asdf3")) #['123', '1.13', '12', '1', '3']#.*默认为贪婪匹配print(re.findall('a.*b','a1b22222222b')) #['a1b22222222b']#.*?为非贪婪匹配:推荐使用print(re.findall('a.*?b','a1b22222222b')) #['a1b']#+print(re.findall('ab+','a')) #[]print(re.findall('ab+','abbb')) #['abbb']#{n,m}print(re.findall('ab{2}','abbb')) #['abb']print(re.findall('ab{2,4}','abbb')) #['abb']print(re.findall('ab{1,}','abbb')) #'ab{1,}' ===> 'ab+'print(re.findall('ab{0,}','abbb')) #'ab{0,}' ===> 'ab*'#[]print(re.findall('a[1*-]b','a1b a*b a-b')) #[]内的都为普通字符了,且如果-没有被转意的话,应该放到[]的开头或结尾print(re.findall('a[^1*-]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[0-9]b','a1b a*b a-b a=b')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-z]b','a1b a*b a-b a=b aeb')) #[]内的^代表的意思是取反,所以结果为['a=b']print(re.findall('a[a-zA-Z]b','a1b a*b a-b a=b aeb aEb')) #[]内的^代表的意思是取反,所以结果为['a=b']#\# print(re.findall('a\\c','a\c')) #对于正则来说a\\c确实可以匹配到a\c,但是在python解释器读取a\\c时,会发生转义,然后交给re去执行,所以抛出异常print(re.findall(r'a\\c','a\c')) #r代表告诉解释器使用rawstring,即原生字符串,把我们正则内的所有符号都当普通字符处理,不要转义print(re.findall('a\\\\c','a\c')) #同上面的意思一样,和上面的结果一样都是['a\\c']#():分组print(re.findall('ab+','ababab123')) #['ab', 'ab', 'ab']print(re.findall('(ab)+123','ababab123')) #['ab'],匹配到末尾的ab123中的abprint(re.findall('(?:ab)+123','ababab123')) #findall的结果不是匹配的全部内容,而是组内的内容,?:可以让结果为匹配的全部内容print(re.findall('href="(.*?)"','点击'))#['http://www.baidu.com']print(re.findall('href="(?:.*?)"','点击'))#['href="http://www.baidu.com"']#|print(re.findall('compan(?:y|ies)','Too many companies have gone bankrupt, and the next one is my company'))

 

# ===========================re模块提供的方法介绍===========================import re#1print(re.findall('e','alex make love') )   #['e', 'e', 'e'],返回所有满足匹配条件的结果,放在列表里#2print(re.search('e','alex make love').group()) #e,只到找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()方法得到匹配的字符串,如果字符串没有匹配,则返回None。#3print(re.match('e','alex make love'))    #None,同search,不过在字符串开始处进行匹配,完全可以用search+^代替match#4print(re.split('[ab]','abcd'))     #['', '', 'cd'],先按'a'分割得到''和'bcd',再对''和'bcd'分别按'b'分割#5print('===>',re.sub('a','A','alex make love')) #===> Alex mAke love,不指定n,默认替换所有print('===>',re.sub('a','A','alex make love',1)) #===> Alex make loveprint('===>',re.sub('a','A','alex make love',2)) #===> Alex mAke loveprint('===>',re.sub('^(\w+)(.*?\s)(\w+)(.*?\s)(\w+)(.*?)$',r'\5\2\3\4\1','alex make love')) #===> love make alexprint('===>',re.subn('a','A','alex make love')) #===> ('Alex mAke love', 2),结果带有总共替换的个数#6obj=re.compile('\d{2}')print(obj.search('abc123eeee').group()) #12print(obj.findall('abc123eeee')) #['12'],重用了obj

  

import reprint(re.findall("<(?P
\w+)>\w+
","

hello

")) #['h1']print(re.search("<(?P
\w+)>\w+
","

hello

").group()) #

hello

print(re.search("<(?P
\w+)>\w+
","

hello

").groupdict()) #

hello

print(re.search(r"<(\w+)>\w+
","

hello

").group())print(re.search(r"<(\w+)>\w+
","

hello

").group())

  

#补充二import re#使用|,先匹配的先生效,|左边是匹配小数,而findall最终结果是查看分组,所有即使匹配成功小数也不会存入结果#而不是小数时,就去匹配(-?\d+),匹配到的自然就是,非小数的数,在此处即整数#print(re.findall(r"-?\d+\.\d*|(-?\d+)","1-2*(60+(-40.35/5)-(-4*3))")) #找出所有整数['1', '-2', '60', '', '5', '-4', '3']#找到所有数字:print(re.findall('\D?(\-?\d+\.?\d*)',"1-2*(60+(-40.35/5)-(-4*3))")) # ['1','2','60','-40.35','5','-4','3']#计算器作业参考:http://www.cnblogs.com/wupeiqi/articles/4949995.htmlexpression='1-2*((60+2*(-3-40.0/5)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))'content=re.search('\(([\-\+\*\/]*\d+\.?\d*)+\)',expression).group() #(-3-40.0/5)

  

#为何同样的表达式search与findall却有不同结果:print(re.search('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))").group()) #(-40.35/5)print(re.findall('\(([\+\-\*\/]*\d+\.?\d*)+\)',"1-12*(60+(-40.35/5)-(-4*3))")) #['/5', '*3']#看这个例子:(\d)+相当于(\d)(\d)(\d)(\d)...,是一系列分组print(re.search('(\d)+','123').group()) #group的作用是将所有组拼接到一起显示出来print(re.findall('(\d)+','123')) #findall结果是组内的结果,且是最后一个组的结果

  

#_*_coding:utf-8_*___author__ = 'Linhaifeng'#在线调试工具:tool.oschina.net/regex/#import res='''http://www.baidu.comegon@oldboyedu.com你好010-3141'''#最常规匹配# content='Hello 123 456 World_This is a Regex Demo'# res=re.match('Hello\s\d\d\d\s\d{3}\s\w{10}.*Demo',content)# print(res)# print(res.group())# print(res.span())#泛匹配# content='Hello 123 456 World_This is a Regex Demo'# res=re.match('^Hello.*Demo',content)# print(res.group())#匹配目标,获得指定数据# content='Hello 123 456 World_This is a Regex Demo'# res=re.match('^Hello\s(\d+)\s(\d+)\s.*Demo',content)# print(res.group()) #取所有匹配的内容# print(res.group(1)) #取匹配的第一个括号内的内容# print(res.group(2)) #去陪陪的第二个括号内的内容#贪婪匹配:.*代表匹配尽可能多的字符# import re# content='Hello 123 456 World_This is a Regex Demo'## res=re.match('^He.*(\d+).*Demo$',content)# print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字#非贪婪匹配:?匹配尽可能少的字符# import re# content='Hello 123 456 World_This is a Regex Demo'## res=re.match('^He.*?(\d+).*Demo$',content)# print(res.group(1)) #只打印6,因为.*会尽可能多的匹配,然后后面跟至少一个数字#匹配模式:.不能匹配换行符content='''Hello 123456 World_Thisis a Regex Demo'''# res=re.match('He.*?(\d+).*?Demo$',content)# print(res) #输出None# res=re.match('He.*?(\d+).*?Demo$',content,re.S) #re.S让.可以匹配换行符# print(res)# print(res.group(1))#转义:\# content='price is $5.00'# res=re.match('price is $5.00',content)# print(res)## res=re.match('price is \$5\.00',content)# print(res)#总结:尽量精简,详细的如下    # 尽量使用泛匹配模式.*    # 尽量使用非贪婪模式:.*?    # 使用括号得到匹配目标:用group(n)去取得结果    # 有换行符就用re.S:修改模式#re.search:会扫描整个字符串,不会从头开始,找到第一个匹配的结果就会返回# import re# content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'## res=re.match('Hello.*?(\d+).*?Demo',content)# print(res) #输出结果为None## import re# content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'## res=re.search('Hello.*?(\d+).*?Demo',content) ## print(res.group(1)) #输出结果为#re.search:只要一个结果,匹配演练,import recontent='''
1
',content)# print(res.group(1))#re.findall:找到符合条件的所有结果# res=re.findall('
',content)# for i in res:# print(i)#re.sub:字符串替换import recontent='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'# content=re.sub('\d+','',content)# print(content)#用\1取得第一个括号的内容#用法:将123与456换位置# import re# content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'## # content=re.sub('(Extra.*?)(\d+)(\s)(\d+)(.*?strings)',r'\1\4\3\2\5',content)# content=re.sub('(\d+)(\s)(\d+)',r'\3\2\1',content)# print(content)# import re# content='Extra strings Hello 123 456 World_This is a Regex Demo Extra strings'## res=re.search('Extra.*?(\d+).*strings',content)# print(res.group(1))# import requests,re# respone=requests.get('https://book.douban.com/').text# print(respone)# print('======'*1000)# print('======'*1000)# print('======'*1000)# print('======'*1000)# res=re.findall('
.*?more-meta.*?author">(.*?)(.*?)(.*?)',respone,re.S)# # res=re.findall('
(.*?)(.*?)(.*?)
.*?',respone,re.S)### for i in res:# print('%s %s %s %s' %(i[0].strip(),i[1].strip(),i[2].strip(),i[3].strip()))

  

练习

(1).编写验证身份证的正则

(2).编写验证手机号的正则

(3).编写验证邮箱地址的正则

 

 

 

转载于:https://www.cnblogs.com/ZKPython/p/10712861.html

你可能感兴趣的文章
Activiti 5.17 实体对象与类和数据库表的映射
查看>>
【转】SVN服务器端安装、配置与管理--不错
查看>>
Fragment中的setUserVisibleHint()方法调用
查看>>
获取、增加、修改、删除sqlserver字段描述及快速查看表字段与描述
查看>>
转FTP协议详解
查看>>
js继承实例
查看>>
ABP源码分析三十八: ABP.Web.Api.OData
查看>>
[PHP] 看博客学习观察者模式
查看>>
索引失效的情况
查看>>
MySql 里的IFNULL、NULLIF和ISNULL用法区别
查看>>
[mybatis] mybatis错误:Invalid bound statement (not found)
查看>>
读取excel文件内容代码
查看>>
各高级语言特点与比较
查看>>
iOS地图 -- 区域监听的实现和小练习
查看>>
Spring Boot实现一个监听用户请求的拦截器
查看>>
Java多线程总结之线程安全队列Queue
查看>>
百度编辑器 Ueditor 下拉处增加字体
查看>>
WPF 虚拟化 VirtualizingWrapPanel 和 VirtualLizingTilePanel
查看>>
Redis快速入门
查看>>
nodejs 相关
查看>>