python基础之坑爹正则表达式
python基础之坑爹正则表达式
概述
re模块就是python语言中的正则表达式,拆出来单独写一条blog是因为正则表达式本身就是比较庞大的知识,写具体些让自己以后方便查找。
IP:
^(25[0-5]|2[0-4]\d|[0-1]?\d?\d)(\.(25[0-5]|2[0-4]\d|[0-1]?\d?\d)){3}$
手机号:
^1[3|4|5|8][0-9]\d{8}$
由于在python中,“\”也被定义为转义字符,因此两个python中的“\”才能代表一个正则中的“\”,这就导致了大量的“\”重复。为了解决这一问题,python提供了原生字符的办法。也就是在字符串前面加上一个“r”,代表此字符串中的“\”可直接用于正则表达式,而不用再次转义。因此,请养成在python的正则表达式字符串的前面添加一个“r“的好习惯。
字符
字符匹配分为普通字符和元字符.
- 大多数字符都会和自身匹配
- 元字符,元字符在[]中没有特殊意义,元字符包括:
元字符 | 含义 |
---|---|
. | 匹配除换行符外的所有字符 |
\w | 匹配字母或者数字或者下划线或汉字 |
\W | 匹配任何非字母或数字或下划线,汉字 |
\s | 匹配任意的空白符,相当于[ \t\n\r\f\v] |
\S | 匹配任意非空白字符 |
\d | 匹配任意十进制数字 |
\D | 匹配任意非数字字符 |
\b | 匹配单词的开始或者结束,即单词和空格的位置,只是匹配字符串开头结尾及空格回车等的位置, 不会匹配空格符本身 |
^ | 匹配字符串的开始 |
匹配字符串的结束 | |
* | 重复0次或更多次 |
+ | 重复1次或多次 |
? | 重复0次或1次 |
{n} | 重复n次 |
{n,} | 重复n次或更多次 |
{n,m} | 重复n到m次 |
[] | 用来指定一个字符集和范围,字符可以单个列出,也可以用“-”号分隔的两个给定.字符来表示一个字符区间。例如,[abc] 将匹配"a", "b", 或 "c"中的任意一个字符;也可以用区间[a-c]来表示同一字符集,和前者效果一致 |
\ | 反斜杠跟后面的元字符,去除元字符的特殊功能;与普通字符一起,实现特殊功能. |
() | 分组功能 |
字符中需要注意的事项
- 如果元字符存在于[]中的字符类中时,只有字符^,-,\有特殊含义.其他无特殊意义.例如:
例如,[akm\(]将匹配字符"a", "k", "m", 或 "\)" 中的任意一个;"$"通常用作元字符,但在字符类别里,其特性被除去,恢复成普通字符。
元字符 | 含义 |
---|---|
\ | 仍表示转义 |
- | 表示范围 |
^ | ^放在支付前面,表示非 |
- *?,+?,??,{m,n}? 前面的*,+,?等都是贪婪匹配,也就是尽可能匹配,后面加?号使其变成惰性匹配,后面加个问号,将策略改为非贪婪,只匹配尽量少的RE,来个例子吧:
>>> re.findall(r"a(\d+?)","a23b") # 非贪婪模式
['2']
>>> re.findall(r"a(\d+)","a23b")
['23']
- \b 就是用在你匹配整个单词的时候。 如果不是整个单词就不匹配。 你想匹
配 I 的话,你知道,很多单词里都有I的,但我只想匹配I,就是“我”,这个时
候用 \bI\b
re模块中的函数
函数 | 描述 | 返回值 |
---|---|---|
compile(pattern[, flags]) | 根据包含正则表达式的字符串创建模式对象 | re模块的对象 |
search(pattern, string[, flags]) | 在字符串中寻找模式 | 第一个匹配到或者None |
match(pattern, string[, flags]) | 在字符串的开始处匹配模式 | 在字符串开头匹配的对象或者None |
split(pattern, string[, maxsplit=0,flags]) | 根据模式的匹配项来分割字符串 | 分割后的字符串列表 |
findall(pattern, string,flags) | 列出字符串中模式的所有匹配项 | 所有匹配到的字符串列表 |
sub(pat,repl, string[,count=0,flags]) | 将字符串中所有的pat的匹配项用repl替换 | 完成替换后的新字符串 |
finditer(pattern, string,flags) | 将所有匹配到的项生成一个迭代器 | 所有匹配到的字符串组成的迭代器 |
subn(pat,repl, string[,count=0,flags]) | 在替换字符串后,同时报告替换的次数 | 完成替换后的新字符串以及替换的次数,返回值为元组数据 |
escape(string) | 将字符串中所有特殊正则表达式字符串转义 | 转义后的字符串 |
purge(pattern) | 清空正则表达式 | |
template(pattern[,flags]) | 编译一个匹配模板 | 模式对象 |
fullmatch(pattern, string[, flags]) | match函数的全字符串匹配版本 | 类似match的返回值 |
compile
将正则表达式转换为模式对象,提高工作效率。使用compile转换后,以后在每次模式使用时直接调用即可!经过compile转换的正则也能使用普通的re函数。
import re
res=re.compile(r'abc')
print(res.match('abcde'))
print(res.match('abcd123').group)
print(res.match('abcd123').group())
输出:
<_sre.SRE_Match object; span=(0, 3), match='abc'>
<built-in method group of _sre.SRE_Match object at 0x0000016911B395E0>
abc
从输出的结果我们可以看出来,compile处理后,返回的是re对象。事实上,compile是在调用match,findall函数之前默认优先编译的一步,所有我们可以在重复调用的某匹配的时候,可先将re.compile赋值于一个变量。
match
match对指定字符串的开头进行匹配,匹配成功后返回一个match的object,如果匹配不成功返回None!
res=re.match(r'abc','123')
print(res)
res1=re.match(r'abc','abc23')
print(res1)
print(res1.start())
print(res1.end())
print(res1.span())
print(res1.group())
out:
None
<_sre.SRE_Match object; span=(0, 3), match='abc'>
0
3
(0, 3)
abc
out中span表示匹配到数字的下标范围,从0到2,所以与列表、字典中取值是相同的
group()是用来直接查看匹配的结果的
search
search用来在指定字符串中查找,返回值为第一个匹配到的字符串
使用方法和match类似
res=re.search(r'abc','123abcsdfsdfsdfabc')
print(res.group())
print(res.start())
print(res.end())
print(res.span())
结果:
abc
3
6
(3, 6)
findall
findall是搜索指定字符串中的所有指定匹配项,返回值为一个列表,如果没有匹配项,那么返回的是一个空列表,而且,findall不需要group()
res=re.findall(r'efg','12efg,sdf,efgsdfsd')
print(res)
res1=re.findall(r'efg','12asdfasdfasdf')
print(res1)
out:
['efg', 'efg']
[]
split
split类似字符串中的分割,用来指定字符串为分隔符,将匹配目标分割成列表形式。而且split有一个maxsplit的参数,用来指定分割的次数。
s='1*8+2-6*-10'
res=re.split(r'[\+\-\*\/]',s)
print(res)
res1=re.split(r'[\+\-\*\/]',s,maxsplit=3)
print(res1)
out:
['1', '8', '2', '6', '', '10'] #1
['1', '8', '2', '6*-10']
注意看结果,#1标志中,为什么第一行的结果,索引-2会是一个空值呢,,是因为"6*-10",将*切割,10前面的负号和星号中间为空值。
而利用re模块中牛逼哄哄的分组功能,能将分割出来的字符串包括分隔符都加入列表中。来看下:
s='1*8+2-6*-10'
res2=re.split(r'([\+\-\*\/])',s)
print(res2)
out:
['1', '*', '8', '+', '2', '-', '6', '*', '', '-', '10']
sub
sub类似字符串中的replace功能,用指定的内容替换匹配到的字符或字符串,同时也可以指定替换次数,使用count= 来指定,或者直接数字也可。
s='hello,I am cc!What the fuck day!'
res=re.sub(r'a','xxx',s)
print(res)
res2=re.sub(r'a','xxx',s,count=2)
print(res2)
out:
hello,I xxxm cc!Whxxxt the fuck dxxxy!
hello,I xxxm cc!Whxxxt the fuck day!
subn
看代码吧,同上,只不过比sub多了替换次数,返回值为元组
s='hello,I am cc!What the fuck day!'
res=re.subn(r'a','xxx',s)
print(res)
print(type(res))
out:
('hello,I xxxm cc!Whxxxt the fuck dxxxy!', 3)
<class 'tuple'>
group和groups
groups返回元组,group返回的是字符串
直接看代码吧:
a = "123abc456"
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).groups())
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).group())
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).group(0))
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).group(1))
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).group(2))
print(re.search(r"([0-9]*)([a-z]*)([0-9]*)", a).group(3))
out:
('123', 'abc', '456')
123abc456
123abc456
123
abc
456
flag编译标识
flag为re匹配时的匹配模式,有X I M S A L U,7种模式.
标识符 | 全拼 | 作用 |
---|---|---|
I | IGNORECASE | 忽略大小写 |
L | LOCALE | 使\w, \W, \b, \B, \d, \D依赖于本地设置 |
M | MULTILINE | 让正则表达式的^和$符号可以适应多行模式的字符串 |
X | VERBOSE | 注释模式 |
A | ASCII | 对于字符串,使得\w, \W, \b, \B, \d, \D只匹配ACSII码字符集,而不是整个Unicode字符集(默认);对于bytes模式,这个编译标志是默认设置,不需要特别指定。 |
S | DOTALL | 使 "." 特殊字符完全匹配任何字符,包括换行;没有这个标志, "." 匹配除了换行外的任何字符 |
U | UNICODE | 兼容模式。在字符串模式下被忽略(默认模式),在字节模式下被禁止 |
M说明下:
s='\n123\n'
res=re.search(r'^123',s)
print(res.group())
这么执行会报错.
但如果使用下面re.M就会正常:
res1=re.search(r'^123',s,re.M)
print(res1.group())
分组
先上例子:
>>> p = re.compile('(a(b)c)d')
>>> m = p.match('abcd')
>>> m.group(0)
'abcd'
>>> m.group(1)
'abc'
>>> m.group(2)
'b'
分组是在re中比较牛逼的东西,功能:去已经匹配到的结果中再提取数据,相当于二次过滤.
提取分组结果使用group groups groupdict
先来看下无分组的结果:
s='abc23434efdabceab'
res=re.match(r'a\w+',s)
print(res.group())
print(res.groups())
print(res.groupdict())
out:
abc23434efdabceab
()
{}
再来看有分组的:
s='abc23434efdabceab2'
res=re.match(r'a(\w+).*(?P<name>\d)$',s)
print(res.group())
print(res.groups())
print(res.groupdict())
out:
abc23434efdabceab2
('bc23434efdabceab', '2')
{'name': '2'}
解释下:匹配时是按r''中的整体去匹配的,第一次匹配完之后,然后再用括号去匹配.有两个括号,那就是从匹配到的结果中,再过滤出两个匹配的结果.再看个例子:
s='abc23434efdabceab2'
res=re.search(r'a(\w+).*(?P<name>\d)$',s)
print(res)
print(res.group())
print(res.group(0))
print(res.group(1))
print(res.group(2))
print(res.groups())
print(res.groupdict())
out:
<_sre.SRE_Match object; span=(0, 18), match='abc23434efdabceab2'>
abc23434efdabceab2
abc23434efdabceab2
bc23434efdabceab
2
('bc23434efdabceab', '2')
{'name': '2'}
可以看出来,group 结果的字符串,groups是元组,groupdict是字典.在group结果中,获取分组结果时,取括号的索引即可,第几个就是group(几),group(0)是第一次匹配出的结果本身
findall,split中的分组有歧义
origin = "hello alex bcd alex lge alex acd 19"
r = re.split("a(le)x", origin)
print(r)
out:
['hello ', 'le', ' bcd ', 'le', ' lge ', 'le', ' acd 19']
s='abc1223434efdabc34121224eabc12'
res=re.findall(r'a(bc)(12)*',s)
print(res)
out:
[('bc', '12'), ('bc', ''), ('bc', '12')]
sub中没有分组的概念
s='abc1223434efdabc34121224eabc12'
res=re.sub(r'a(bc)(12)*','xxx',s)
print(res)
out:
xxx23434efdxxx34121224exxx
看来并没有什么乱用!
python基础之坑爹正则表达式的更多相关文章
- python基础之 re(正则表达式)模块学习
今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的资料.这里主要介绍Python中常用的正则表达式处理函数. re.match re.match 尝试从 ...
- Python基础:28正则表达式
一:概述 正则表达式(RE)为高级文本模式匹配,以及搜索-替代等功能提供了基础.正则表达式(RE)是一些由字符和特殊符号组成的字符串,它们能匹配多个字符串.Python通过标准库的re模块支持正则表达 ...
- 【笔记】Python基础七:正则表达式re模块
一,介绍 正则表达式(RE)是一种小型的,高度专业化的编程语言,在python中它内嵌在python中,并通过re模块实现.正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行. 字符匹配 ...
- python基础学习笔记——正则表达式
1.什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中,并通过 r ...
- python 基础(十四) 正则表达式
正则表达式 概念: 正则匹配就是一个模糊的匹配 只要符合我的匹配规则 就会认为是正确的数据(精确的匹配) 1.[] #代表原子表把想要匹配的内容写入原子表中 匹配包含的任意一位字符 [a] ...
- python基础:8.正则表达式
1.概念 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. re模块的常见方法: ...
- python基础知识(正则表达式)
使用正则表示式分割字符串 split() re.split(pattern,string,[maxsplit],[flags]) re.split(指定一个模式字符串,要匹配的字符串,最大的拆分次数, ...
- python基础-6.2正则表达式,计算器练习
content = "1-2*((60-30+(1-40/5*5+3-2*5/3)*(9-2*5/3+7/3*99/4*2998+10*568/14))-(-4*3)/(16-3*2))&q ...
- Python基础之 正则表达式指南
本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...
随机推荐
- 线性查找与二分查找(python)
# -*- coding: utf-8 -*- number_list = [0, 1, 2, 3, 4, 5, 6, 7] def linear_search(value, iterable): f ...
- ReLU激活函数
参考:https://blog.csdn.net/cherrylvlei/article/details/53149381 首先,我们来看一下ReLU激活函数的形式,如下图: 单侧抑制,当模型增加N层 ...
- CentOs 6语言改成中文
1.在root权限下 切换到root下:su - root 查看当前语言环境:locale -a (注意中间有空格) 如果看到 zh_CN.UTF-8(这个是中文简体)说明你的系统支持中文语言: 没 ...
- jQuery模拟键盘打字逐字逐句显示文本
jQuery模拟键盘打字逐字逐句显示文本 html代码 <!doctype html> <html lang="zh"> <head> < ...
- Spring 对事务的整合
对事务的复习 什么是事务: 事务(TRANSACTION) 是作为单个逻辑工作单元执行的一系列操作. 多个操作作为一个整体向系统提交,要么都执行,要么都不执行. 事务是一个不可分割的逻辑单元. 事务的 ...
- java获取远程服务器应用程序服务状态
package lct.conference.test; import java.io.BufferedReader; import java.io.IOException; import java. ...
- 三十一.MySQL存储引擎 、 数据导入导出 管理表记录 匹配条件
1.MySQL存储引擎的配置 查看服务支持的存储引擎 查看默认存储类型 更改表的存储引擎 设置数据库服务默认使用的存储引擎 1.1 查看存储引擎信息 mysql> SHOW ENGINES\G ...
- 后台(一)vue+element-ui (按需加载)
vue init webpack 项目名称 npm install axios //先安装! npm install --save axios vue-ax ...
- react页面跳转 window.location.href和window.open的几种用法和区别
https://www.cnblogs.com/Qian123/p/5345298.html
- 使用tfrecord建立自己的数据集
注意事项: 1.关于输入图像格式的问题 使用io.imread()的时,根据输入图像确定as_grey的参数值. 转化为字符串之后(image.tostring) ,最后输出看下image_r ...