python正则表达式

目录

1.re模块除了能够完成使用正则表达式来匹配字符串,还可以匹配单字符

2.原生字符串

3.匹配多个字符的相关格式

4.限定匹配的边界

5.还有一些匹配分组

6.re模块的高级用法

7.group与groups

8.python的贪婪和非贪婪


正则表达式使用单个字符串来描述、匹配一系列匹配某个句法规则的字符串。

import re

#result=re.match(正则表达式,要匹配的字符串)  #若匹配,返回匹配对象,否则返回None
#result.group()  #用来返回字符串的匹配部分

#re.match()能够匹配以XXX开头的字符串
result=re.match("itcast","itcast.cn")  #re模块匹配
print(result.group())  #返回itcast

#r1=re.match("abc","def")
#r1.group()  #匹配不上,返回none

#r2=re.match("abc","abcde")
#r2.group()   #正确,返回abc

#r3=re.match("abc","deabc")
#r3.group()   #错误,只能匹配以abc开头的

1.re模块除了能够完成使用正则表达式来匹配字符串,还可以匹配单字符

#coding=utf-8
import re
#re.match()能够匹配以XXX开头的字符串
result=re.match(".","itcast.cn")  #.可以匹配任意1个字符(除了\n)
print(result.group()) #i

r1=re.match("[hH]","Hello python") #[]可以匹配以h或H开头的字符
print(r1.group())  #H
r2=re.match("[0-9]","45hello")
print(r2.group())  #4

#r3=re.match("阳历\d号","阳历19号了")
r3=re.match("\d","19号了")
print(r3.group())  #1  我的这里不能匹配汉字,只能匹配字符串

2.原生字符串

与大多数编程语语言相同,正则表达式里使用”\“作为转义字符,这就可能造成反斜杠困扰。假如你需要匹配本中的字符”\“,那么使用编程语言表示的正则表达式里将需要4个反斜杠”\\“:前两个和后两个分别.于在编程语言转义成反斜杠,转换成两个反斜杠后再在正则表达式里转义成一个反斜杠。Python里的原生字符串很好地解决了这个问题,有了原始字符串,你再也不用担心是不是漏写了反斜杠,写出来的表达式也更直观。

python中字符串前面加上 r 表示原生字符串

#coding=utf-8
import re
#re.match()能够匹配以XXX开头的字符串
r1=re.match("c:\\\\a","c:\\a")  #.可以匹配任意1个字符(除了\n)
print(r1.group()) #c:\a

#python中字符串前面加上 r 表示原生字符串
r2=re.match(r"c:\\a","c:\\a")  #.可以匹配任意1个字符(除了\n)
print(r2.group()) #c:\a

3.匹配多个字符的相关格式

#coding=utf-8
import re
r1=re.match("[A-Z][a-z]*","AbcdeFgh")  #表示匹配的第一个是大写,接下来的小写可以是0到无限次
print(r1.group()) #Abcde

r2=re.match("[A-Za-z_]+[\w_]*","Ab_cde")  #表示匹配的A-Z/a-z/_格式出现1到无数次,然后又出现0到无数次
print(r2.group()) #Ab_cde

r3=re.match("[A-Za-z_]+[\w_]*","_Abcde")
print(r3.group()) #_Abcde

r4=re.match("[A-Za-z_]+[\w_]*","5_Abcde")
#print(r4.group()) #匹配不成功

r5=re.match("[A-Za-z_]?[\d]*","5_Abcde")  #表示匹配的A-Z/a-z/_格式出现0或1次,然后匹配数字0-9
print(r5.group()) #5

r6=re.match("[1-9]?[0-9]","28")  #表示匹配的十位数上有0或1位,用来匹配0-99之间的数字
print(r6.group()) #28

r7=re.match("[1-9]?[0-9]","09")  #表示匹配的十位数上有0或1位,用来匹配0-99之间的数字
print(r7.group()) #0

r8=re.match("[A-Za-z_0-9]{9,18}","1abcd6780_jio0lkujiu888")  #表示匹配的9到18位的密码,每一位可以是大小写、数字、下划线
print(r8.group()) #1abcd6780_jio0lkuj 若超出18位,则只显示前18位

r9=re.match("[A-Za-z_0-9]{9,18}","1abcd8900")  #表示匹配的9到18位的密码,每一位可以是大小写、数字、下划线
print(r9.group()) #1abcd6780_jio0lkuj 若不足9位,则报错

r10=re.match("[A-Za-z_0-9]{9}","1abcd89000")  #表示匹配的9位的密码,每一位可以是大小写、数字、下划线
print(r10.group()) #1abcd8900 若不足9位,则报错,超出则只显示前9位

4.限定匹配的边界

#coding=utf-8
import re
#例子:匹配163.com的邮箱  $限定边界
r1=re.match("[\w]{8,10}@163\.com$","Abcd1234@163.com")  #$表示匹配的必须以@163.com结尾
print(r1.group()) #Abcd1234@163.com

r2=re.match("[\w]{8,10}@163.com$","Abcd1234@163.com")  #$表示匹配的必须以@163.com结尾
print(r2.group()) #Abcd1234@163.com

r3=re.match("^[_][\w]{8,10}@163.com$","_abcd1234@163.com")  #^表示必须以_为开头 $表示必须以@163.com结尾
print(r3.group()) #_abcd1234@163.com

r4=re.match(r".*\bis\b","time is a thief")  #b表示必须以is为边界
print(r4.group()) #time is

r5=re.match(r".*\bis\b","time isnot a thief")
#print(r5.group()) #error

r6=re.match(r".*\Bis\B","timeisnot a thief")  #B表示必须不以is为边界
print(r6.group()) #timeis

5.还有一些匹配分组

#coding=utf-8
import re
#例子:匹配163.com的邮箱  $限定边界
r1=re.match(r"<(\w*)><(\w*)>.*</\2></\1>","<html><hl>www.ab.cn</hl></html>")  #163|qq|gmail表示中间的域名可以是任意一个
print(r1.group()) #<html><hl>www.ab.cn</hl></html>

#\2表示第二个元素,\1表示第一个元素
r2=re.match(r"<(\w*)><(\w*)>.*</\2></\1>","<html><hl>www.ab.cn</hl></htm>")  #163|qq|gmail表示中间的域名可以是任意一个
#print(r2.group()) #<html><hl>www.ab.cn</hl></html>  #由于html与htm不一致,则无法进行匹配

#当以上面方法对逐个元素进行匹配时,按序号容易出错,所以提出下面的命名方法
#其中字母(?P<name>)和(?P=name)中的P大写
r3=re.match(r"<(?P<key1>\w*)><(?P<key2>\w*)>.*</(?P=key2)></(?P=key1)>","<html><hl>www.ab.cn</hl></html>")  #163|qq|gmail表示中间的域名可以是任意一个
print(r3.group()) #<html><hl>www.ab.cn</hl></html>

6.re模块的高级用法

#coding=utf-8
import re

#search 匹配相应项
r1=re.search(r"\d+","访问总次数超过10000,阅读次数超过99999")
print(r1.group()) #10000

#findall  统计所有满足的项
r2=re.findall(r"\d+","访问总次数超过10000,阅读次数超过99999")
print(r2) #['10000', '99999']次数r2是列表形式,故不能再用上面方式打印

#sub 将匹配到的数据进行替换
#方法一:re.sub("要替换哪些项","要替换成什么量","替换项所在语句")
r3=re.sub(r"\d+","888888","访问总次数超过10000,阅读次数超过99999")
print(r3) #访问总次数超过888888,阅读次数超过888888
#方法二:re.sub("要替换哪些项",替换函数,"替换项所在语句")
def add(temp):
    strnum=temp.group()
    num=int(strnum)+5
    return str(num)
r4=re.sub(r"\d+",add,"访问总次数超过10000,阅读次数超过99999")
print(r4) #访问总次数超过10005,阅读次数超过100004

#split根据匹配进行切割字符串,并返回一个列表
r5=re.split(r":| ","message:xiaozhang 29 shanxi") #:后,以空格划分
#r5=re.split(r" ","message:xiaozhang 29 shanxi") #以空格划分
print(r5)  #['message', 'xiaozhang', '29', 'shanxi']

7.group与groups

#coding=utf-8
import re

#group与groups的用法
r1=re.match(r"([^-]*)-(\d+)","010-12345678")
#r1=re.match(r"([\d]*)-(\d+)","010-12345678")  #与上面写法均可
print(r1.group()) #010-12345678
print(r1.groups()) #('010', '12345678')
print(r1.group(1)) #010
print(r1.group(2)) #12345678
#print(r1.group(3)) #no such group
print(r1.groups(1)) #('010', '12345678')
print(r1.groups(2)) #('010', '12345678')
print(r1.groups(3)) #('010', '12345678')

8.python的贪婪和非贪婪

python里数量词默认是贪婪的(在少数语言里也可能是默认非贪婪),总是尝试匹配尽可能多的字符;非贪婪则相反,总是尝试匹配尽可能少的字符。在”*“,”?“,”+“,”{m,n}“后面加上?,使贪婪变成非贪婪。

#coding=utf-8
import re

s="This is a number 234-235-22-423"
r1=re.match(".+(\d+-\d+-\d+-\d+)",s)  #默认是贪婪模式
print(r1.group()) #This is a number 234-235-22-423
print(r1.group(1))  #4-235-22-423
#“.+”会从字符串的启始处抓取满⾜模式的最⻓字符,其中包括我们想得到的第⼀个整型字段的中的⼤
#部分,“\d+”只需⼀位字符就可以匹配,所以它匹配了数字“4”,⽽“.+”则匹配了从字符串起始到
# 这个第⼀位数字4之前的所有字符。
r2=re.match(".+?(\d+-\d+-\d+-\d+)",s)  #添上?,表示设置为非贪婪模式
print(r2.group()) #This is a number 234-235-22-423
print(r2.group(1))  #234-235-22-423

r3=re.match(r"aa(\d+)","aa2343ddd")
r4=re.match(r"aa(\d+?)","aa2343ddd")
r5=re.match(r"aa(\d+)ddd","aa2343ddd")
r6=re.match(r"aa(\d+?)ddd","aa2343ddd")
print(r3.group(1))  #2343
print(r4.group(1))  #2
print(r5.group(1))  #2343
print(r6.group(1))  #2343

https://blog.csdn.net/lxcnn/article/details/4756030  (很棒的博客)

还可参考:

https://blog.csdn.net/wenhai_dai/article/details/52877978

http://www.runoob.com/regexp/regexp-tutorial.html

#yu:参考上面正则表达式,解决series下的日期识别问题
import numpy as np
import pandas as pd
import re

'''
#邮箱识别实例
data1=pd.Series({'li':'120@qq.com', 'wang':'5632@qq.com', 'chen':'8622@xinlang.com', 'zhao':'9872@163.com', 'sun':'5243@gmail.com'})
pattern1 = re.compile(r'(\d*)@([a-z]+)\.([a-z]{2,4})')
result1=data1.str.match(pattern1)
print(result1)
print(data1.str.extract(pattern1,expand=True))  #匹配不上的会用nan代替
'''

#日期书写不规范识别实例 
d1=pd.Series({'1':'生产日期:2017年3月26日 0:00:00','2':'2017/4/13', '3':'2017年10.3','4':'生产日期:2017年03月26日', '5':'2016//9//25',
              '6':'2017-08-06购进','7':'20170112','8':'购进日期2016年12月14日/20160726','9':'2017-07-23/20170723B','10':'2017/72','11':'/'})
print(d1)
pattern=re.compile(r".*?(\d{4}).*?(\d{1,2}).*?(\d{1,2}).*")
result=d1.str.match(pattern)
#print(d1.str.extractall(pattern))  #只返回匹配成功的
print(d1.str.extract(pattern,expand=True))  #匹配不上的会用nan代替
'''
1      生产日期:2017年3月26日 0:00:00
10                     2017/72
11                           /
2                    2017/4/13
3                    2017年10.3
4             生产日期:2017年03月26日
5                  2016//9//25
6                 2017-08-06购进
7                     20170112
8     购进日期2016年12月14日/20160726
9         2017-07-23/20170723B
dtype: object
       0    1    2
1   2017    3   26
10  2017    7    2
11   NaN  NaN  NaN
2   2017    4   13
3   2017   10    3
4   2017   03   26
5   2016    9   25
6   2017   08   06
7   2017   01   12
8   2016   12   14
9   2017   07   23
'''

注:

"""  

"""表示可以保留字符串的原始格式,包括里面的换行、引号之类的,会在内存值存储,文件过大也会影响执行效率,而#表示遇见就直接跳过,所以引号注释不等于#注释

多行注释:ctrl+/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值