正则表达式
一,正则表达式
特点,贪婪匹配,它会在允许的范围内取最长的结果。
在应用方面只和字符串打交道。具体应用途径:
1.把一个文件中所有的手机号码都找出来,需要从大段的文字中找到符合规则的内容 # open打开文件
# 读文件 str
# 从一长串的字符串中找到所有的11位数字
# 一个字符一个字符的读
2.输入手机号
# 验证这个手机号是否合法
# 给这个手机号发送一个验证码
# 用户收到验证码 填写验证码
# 完成注册
# 正则表达式
# 从大段的文字中找到符合规则的内容
# 爬虫 从网页的字符串中获取你想要的数据
# 日志分析 提取 2018-8-12 10:---- 花的所有钱
# 什么是日志 :
# 2018-8-12 10:00:00 楼下早点摊 3.00
# 判断某个字符串是否完全符合规则
# 表单验证 : 手机号 qq号码 邮箱 银行卡 身份证号 密码
二,字符组
| [0-9] | 匹配数字 |
| [a-z] | 匹配小写字母 |
| [A-Z] | 匹配大写字母 |
| [a-zA-Z] | 匹配大小写字母 |
| [a-zA-Z0-9] | 匹配大小写字母+数字 |
| [a-zA-Z0-9_] | 匹配数字字母下滑线 |
三,元字符
| \w | 匹配数字字母下滑线(等于[a-zA-Z0-9_]) |
| \d | 匹配所有的数字(等于[0-9]) |
| \s |
匹配所有的空白符(等于回车/换行符 制表符 空格 space [\n\t ]) # 匹配换行符 回车 \n (\W \D \S 和\w \d \s取反 # [\s\S] [\d\D] [\w\W]是三组全集 意思是匹配所有字符) |
| \b | 表示单词的边界 |
| 总结为:\w \d \s(\n\t) \b \W \D \S | |
| ^ | 匹配一个字符串的开始 |
| $ | 匹配一个字符串的结束 |
| . | 表示匹配除换行符之外的所有字符 |
| [] | 只要出现在中括号内的内容都可以被匹配 |
| [^] | 只要不出现在中括号中的内容都可以被匹配(有一些有特殊意义的元字符进入字符组中会回复它本来的意义 : . | [ ] ( )) |
| a|b |
或 符合a规则的或者b规则的都可以被匹配 # 如果a规则是b规则的一部分,且a规则比b规则要苛刻/长,就把a规则写在前面 |
| () | 分组 表示给几个字符加上量词约束的需求的时候,就给这些量词分在一个组 |
三,量词
| {n} | 表示 这个量词之前的字符出现n次 |
| {n,} | 表示这个量词之前的字符至少出现n次 |
| {n,m} | 表示这个量词之前的字符出现n-m次 |
| ? | 表示匹配量词之前的字符出现 0次 或者 1次 表示可有可无 |
| + | 表示匹配量词之前的字符出现 1次 或者 多次 |
| * | 表示匹配量词之前的字符出现 0次 或者 多次 |
|
|
|
四, 贪婪法则
一般元字符都会遵循贪婪法则,是因为回溯算法。也就是在满足条件的情况下,选择最大值。但,当量词后面加上?时,就会变成非贪婪。
即,
#字符+量词+? 约束一个字符连续出现的最少次数 I
#字符+量词+?+x约束一个字符连续出现量词范围内的最少次数,遇到x就立即停


题目:





五,re模块
查找
1 # findall : 匹配所有 每一项都是列表中的一个元素 2 # ret = re.findall('\d+','sjkhk172按实际花费928') # 正则表达式,带匹配的字符串,flag 3 # ret = re.findall('\d','sjkhk172按实际花费928') # 正则表达式,带匹配的字符串,flag 4 # print(ret) 5 6 # search : 只匹配从左到右的第一个,得到的不是直接的结果,而是一个变量,通过这个变量的group方法来获取结果 7 # 如果没有匹配到,会返回None,使用group会报错 8 # ret = re.search('\d+','sjkhk172按实际花费928') 9 # print(ret) # 内存地址,这是一个正则匹配的结果 10 # print(ret.group()) # 通过ret.group()获取真正的结果 11 12 # ret = re.search('\d','owghabDJLBNdgv') 13 # print(ret) 14 # print(ret.group()) 15 16 # ret = re.search('\d+','sjkhk172按实际花费928') 17 # if ret : # 内存地址,这是一个正则匹配的结果 18 # print(ret.group()) # 通过ret.group()获取真正的结果 19 20 21 # match 从头开始匹配,相当于search中的正则表达式加上一个^(个人感觉有点鸡肋) 22 # ret = re.match('\d+$','172sjkhk按实际花费928') 23 # print(ret)
字符串处理的扩展 : 替换 切割
1 # split 2 # s = 'alex|taibai|egon|' 3 # print(s.split('|')) 4 # s = 'alex83taibai40egon25' 5 # ret = re.split('\d+',s) 6 # print(ret) 7 8 # sub # 谁 旧的 新的 替换次数 9 # ret = re.sub('\d+','H','alex83taibai40egon25') 10 # print(ret) 11 # 12 # ret = re.sub('\d+','H','alex83taibai40egon25',1) 13 # print(ret) 14 15 # subn 返回一个元组,第二个元素是替换的次数 16 # ret = re.subn('\d+','H','alex83taibai40egon25') 17 # print(ret)
re模块的进阶 : 时间/空间
1 compile 节省你使用正则表达式解决问题的时间 2 # 编译 正则表达式 编译成 字节码 3 # 在多次使用的过程中 不会多次编译 4 # ret = re.compile('\d+') # 已经完成编译了 5 # print(ret) 6 # res = ret.findall('alex83taibai40egon25') 7 # print(res) 8 # res = ret.search('sjkhk172按实际花费928') 9 # print(res.group()) 10 11 # finditer 节省你使用正则表达式解决问题的空间/内存 12 # ret = re.finditer('\d+','alex83taibai40egon25') 13 # for i in ret: 14 # print(i.group())
总结:
# findall 返回列表 找所有的匹配项
# search 匹配就 返回一个变量,通过group取匹配到的第一个值,不匹配就返回None,group会报错
# match 相当于search的正则表达式中加了一个'^'
# spilt 返回列表,按照正则规则切割,默认匹配到的内容会被切掉
# sub/subn 替换,按照正则规则去寻找要被替换掉的内容,subn返回元组,第二个值是替换的次数
# compile 编译一个正则表达式,用这个结果去search match findall finditer 能够节省时间
# finditer 返回一个迭代器,所有的结果都在这个迭代器中,需要通过循环+group的形式取值 能够节省内存
六,分组,分组的使用对于使用正则表达式时有了更好的准确性
findall可以顺利取到分组中的内容,有一个特殊的语法,就是优先显示分组中的内容
# ret = re.findall('(\w+)',s)
# print(ret)
# ret = re.findall('>(\w+)<',s)
# print(ret)
取消分组优先(?:正则表达式)
# ret = re.findall('\d+(\.\d+)?','1.234*4')
# print(ret)
# 关于分组
# 对于正则表达式来说 有些时候我们需要进行分组,来整体约束某一组字符出现的次数
# (\.[\w]+)?
# 对于python语言来说 分组可以帮助你更好更精准的找到你真正需要的内容
# <(\w+)>(\w+)</(\w+)>
# split
# ret = re.split('\d+','alex83taibai40egon25')
# print(ret)
# ret = re.split('(\d+)','alex83taibai40egon25aa')
# print(ret)
# python 和 正则表达式 之间的特殊的约定
分组命名 (?P<这个组的名字>正则表达式)
# s = '<a>wahaha</a>'
# ret = re.search('>(?P<con>\w+)<',s)
# print(ret.group(1))
# print(ret.group('con'))
# s = '<a>wahaha</a>'
# pattern = '<(\w+)>(\w+)</(\w+)>'
# ret = re.search(pattern,s)
# print(ret.group(1) == ret.group(3))
# 使用前面的分组 要求使用这个名字的分组和前面同名分组中的内容匹配的必须一致
# pattern = '<(?P<tab>\w+)>(\w+)</(?P=tab)>'
# ret = re.search(pattern,s)
# print(ret)
分组取名对于以下的寻找有较好的方便性
# 2018-12-06
# 2018.12.6
# 2018 12 06
# 12:30:30
总结:
正则表达式
# 元字符 : \w \d \s \n \t \W \S \D \b ^ $ . [] [^] () |
# [0-9] \d 这种情况下 应该\d
# [1-9]
# [\da-zA-Z]
# 量词 : {n} {n,} {n,m} * ? +
# 转义符 :
# python str : '\'
# 正则表达式中的'\'到了python中都会变成'\\'
# r'\w' 在python当中\不转义了,在Python中就是一个普通的'\',但是在正则表达式中它还是表示一个转义符
# 贪婪匹配/惰性匹配 :
# .*x 贪婪 匹配任意内容最多次,直到最后一个X停止 回溯算法
# .*?X 惰性 匹配任意内容最少次,遇到第一个X就停止
# re模块
# findall 匹配所有 列表
# search 匹配第一个 变量.group(),没匹配到返回None
# match 从头开始匹配第一个
# split sub subn
# finditer compile
# finditer 返回一个迭代器,所有匹配到的内容需要迭代取到,迭代取到的每一个结果都需要group取具体值
# -- 节省内存空间
# compile 编译,先把一个正则表达式编译,编译之后,在之后多次使用的过程不用重新编译
# -- 节省时间 提高效率
re模块
# findall 匹配所有 列表
# search 匹配第一个 变量.group(),没匹配到返回None
# match 从头开始匹配第一个
# split sub subn
# finditer compile
# finditer 返回一个迭代器,所有匹配到的内容需要迭代取到,迭代取到的每一个结果都需要group取具体值
# -- 节省内存空间
# compile 编译,先把一个正则表达式编译,编译之后,在之后多次使用的过程不用重新编译
# -- 节省时间 提高效率
分组:()
# 1.给不止一个字符的整体做量词约束的时候 www(\.[\w]+)+ www.baidu.com
# 2.优先显示,当要匹配的内容和不想匹配的内容混在一起的时候,
# 就匹配出所有内容,但是对实际需要的内容进行分组
# 3.分组和re模块中的方法 :
# findall : 分组优先显示 取消(?:正则)
# search :
# 可以通过.group(index)来取分组中的内容
# 可以通过.group(name)来取分组中的内容
# 正则 (?P<name>正则)
# 使用这个分组 ?P=name
# split : 会保留分组内的内容到切割的结果中
posted on 2023-11-28 23:53 我才是最帅的那个男人 阅读(20) 评论(0) 收藏 举报

浙公网安备 33010602011771号