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基础之坑爹正则表达式的更多相关文章

  1. python基础之 re(正则表达式)模块学习

    今天学习了Python中有关正则表达式的知识.关于正则表达式的语法,不作过多解释,网上有许多学习的资料.这里主要介绍Python中常用的正则表达式处理函数. re.match re.match 尝试从 ...

  2. Python基础:28正则表达式

    一:概述 正则表达式(RE)为高级文本模式匹配,以及搜索-替代等功能提供了基础.正则表达式(RE)是一些由字符和特殊符号组成的字符串,它们能匹配多个字符串.Python通过标准库的re模块支持正则表达 ...

  3. 【笔记】Python基础七:正则表达式re模块

    一,介绍 正则表达式(RE)是一种小型的,高度专业化的编程语言,在python中它内嵌在python中,并通过re模块实现.正则表达式模式被编译成一系列的字节码,然后由C编写的匹配引擎执行. 字符匹配 ...

  4. python基础学习笔记——正则表达式

    1.什么是正则? 正则就是用一些具有特殊含义的符号组合到一起(称为正则表达式)来描述字符或者字符串的方法.或者说:正则就是用来描述一类事物的规则.(在Python中)它内嵌在Python中,并通过 r ...

  5. python 基础(十四) 正则表达式

    正则表达式 概念: 正则匹配就是一个模糊的匹配 只要符合我的匹配规则 就会认为是正确的数据(精确的匹配) 1.[] #代表原子表把想要匹配的内容写入原子表中   匹配包含的任意一位字符 [a]     ...

  6. python基础:8.正则表达式

    1.概念 正则表达式是对字符串操作的一种逻辑公式,就是用事先定义好的一些特定字符.及这些特定字符的组合,组成一个“规则字符串”,这个“规则字符串”用来表达对字符串的一种过滤逻辑. re模块的常见方法: ...

  7. python基础知识(正则表达式)

    使用正则表示式分割字符串 split() re.split(pattern,string,[maxsplit],[flags]) re.split(指定一个模式字符串,要匹配的字符串,最大的拆分次数, ...

  8. 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 ...

  9. Python基础之 正则表达式指南

    本文介绍了Python对于正则表达式的支持,包括正则表达式基础以及Python正则表达式标准库的完整介绍及使用示例.本文的内容不包括如何编写高效的正则表达式.如何优化正则表达式,这些主题请查看其他教程 ...

随机推荐

  1. 线性查找与二分查找(python)

    # -*- coding: utf-8 -*- number_list = [0, 1, 2, 3, 4, 5, 6, 7] def linear_search(value, iterable): f ...

  2. ReLU激活函数

    参考:https://blog.csdn.net/cherrylvlei/article/details/53149381 首先,我们来看一下ReLU激活函数的形式,如下图: 单侧抑制,当模型增加N层 ...

  3. CentOs 6语言改成中文

    1.在root权限下 切换到root下:su - root 查看当前语言环境:locale -a  (注意中间有空格) 如果看到 zh_CN.UTF-8(这个是中文简体)说明你的系统支持中文语言: 没 ...

  4. jQuery模拟键盘打字逐字逐句显示文本

    jQuery模拟键盘打字逐字逐句显示文本 html代码 <!doctype html> <html lang="zh"> <head> < ...

  5. Spring 对事务的整合

    对事务的复习 什么是事务: 事务(TRANSACTION) 是作为单个逻辑工作单元执行的一系列操作. 多个操作作为一个整体向系统提交,要么都执行,要么都不执行. 事务是一个不可分割的逻辑单元. 事务的 ...

  6. java获取远程服务器应用程序服务状态

    package lct.conference.test; import java.io.BufferedReader; import java.io.IOException; import java. ...

  7. 三十一.MySQL存储引擎 、 数据导入导出 管理表记录 匹配条件

    1.MySQL存储引擎的配置 查看服务支持的存储引擎 查看默认存储类型 更改表的存储引擎 设置数据库服务默认使用的存储引擎 1.1 查看存储引擎信息 mysql> SHOW ENGINES\G ...

  8. 后台(一)vue+element-ui (按需加载)

    vue init webpack    项目名称 npm install axios                    //先安装! npm install --save axios vue-ax ...

  9. react页面跳转 window.location.href和window.open的几种用法和区别

    https://www.cnblogs.com/Qian123/p/5345298.html

  10. 使用tfrecord建立自己的数据集

    注意事项: 1.关于输入图像格式的问题     使用io.imread()的时,根据输入图像确定as_grey的参数值. 转化为字符串之后(image.tostring) ,最后输出看下image_r ...