正则表达式

一,正则表达式
  特点,贪婪匹配,它会在允许的范围内取最长的结果。
在应用方面只和字符串打交道。具体应用途径:
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
# 匹配制表符 tab \t
# 匹配空格

(\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)    收藏  举报

导航