lesson 038 —— re 模块
lesson 038 —— re 模块
关于 re 模块的简单介绍。就其本质而言,正则表达式(Regular Expression 或 RE)是一种小型的、高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。
普通字符
大多数字符和字母都会和自身匹配。
>>> re.findall('alvin','yuanaleSxalexwupeiqi')
['alvin']
元字符
元字符:. ^ $ * + ? { } [ ] | ( ) \
。
1. 元字符之 .
.
是通配符,除了换行符(\n
)之外,其它字符全部可以匹配到。注意:一个 .
只能代替一个字符串,不能代表多个。
>>> import re
>>> ret = re.findall('a..in', 'alinjjssalvinsssainmmmallinsxlimaa\-inxxna\r\inllxal\ninnn')
>>> print(ret)
['alvin', 'allin', 'a\\-in', 'a\r\\in']
2. 元字符之 ^
^
是通配符,表示开头,即以之后的字符开头才匹配。
>>> ret = re.findall('^a..in', 'addinxxalinjjssalvinsssainmmmallinsxlimaa\-inxxna\r\inllxal\ninnn')
>>> print(ret)
['addin']
3. 元字符之 `
$
是通配符,表示结尾,即以之前的字符结尾才匹配。
>>> ret = re.findall('a..in$', 'addinxxalinjjssalvinsssainmmmallinsxlimaa\-inxxna\r\inllxal\ninnaedin')
>>> print(ret)
['aedin']
4. 元字符之 *
*
表示重复的字符,即匹配紧挨着它的前面的字符 0 次 或无穷次 [0, +∞]。并且,它是贪婪匹配(即尽可能多的匹配字符)。
>>> ret = re.findall('abc*e', 'abccccccddef')
>>> print(ret)
[]
>>> ret = re.findall('abc*d', 'abccccccddef')
>>> print(ret)
['abccccccd']
>>> ret = re.findall('abc*d', 'abddef')
>>> print(ret)
['abd']
>>> ret = re.findall('abc*', 'abccccccddef') # 贪婪匹配
>>> print(ret)
['abcccccc']
5. 元字符之 +
+
同样表示重复的字符,它也是贪婪匹配,但是,它匹配的是它前面的字符 1 次或无穷次 [1, +∞]。
>>> ret = re.findall('abc+d', 'abccccccddef')
>>> print(ret)
['abccccccd']
>>> ret = re.findall('abc+d', 'abddef')
>>> print(ret)
[]
>>> ret = re.findall('abc+', 'abccccccddef') # 贪婪匹配
>>> print(ret)
['abcccccc']
6. 元字符之 ?
?
表示匹配它紧挨的前面的字符 0 次或 1 次 [0, 1]。它也是贪婪匹配。
>>> ret = re.findall('abc?d', 'abccccccddef')
>>> print(ret)
[]
>>> ret = re.findall('abc?d', 'abcddef')
>>> print(ret)
['abcd']
>>> ret = re.findall('abc?d', 'abddef')
>>> print(ret)
['abd']
>>> ret = re.findall('abc?d', 'acddef') # 只作用于和它紧挨的那个字符
>>> print(ret)
[]
>>> ret = re.findall('abc?', 'abcccddef') # 表示贪婪匹配
>>> print(ret)
['abc']
7. 元字符之 {}
{}
表示自己定义字符重复的次数。例:{4}
表示重复 4 次;{1,6}
表示重复 1 次到 6 次;{0,}
表示重复 0 次 到无穷次,相当于 *
;{1,}
表示重复 1 次到无穷次,相当于 +
;{0,1}
表示重复 0 次或 1 次,相当于 ?
。它的次数也是贪婪匹配。
>>> ret = re.findall('abc{4}', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['abcccc', 'abcccc', 'abcccc']
>>> ret = re.findall('abc{1,6}', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['abc', 'abcc', 'abccc', 'abcccc', 'abcccccc', 'abcccccc']
>>> ret = re.findall('abc{0,}', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['ab', 'abc', 'abcc', 'abccc', 'abcccc', 'abcccccc', 'abcccccccc']
>>> ret = re.findall('abc{1,}', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['abc', 'abcc', 'abccc', 'abcccc', 'abcccccc', 'abcccccccc']
>>> ret = re.findall('abc{0,1}', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['ab', 'abc', 'abc', 'abc', 'abc', 'abc', 'abc']
8. 前面的 *, +, ?, {}
等都是贪婪匹配
也就是尽可能的匹配,后面加 ?
可以使其变成惰性匹配。
>>> ret = re.findall('abc*?', 'abccccccddef')
>>> print(ret)
['ab']
>>> ret = re.findall('abc+?', 'abccccccddef')
>>> print(ret)
['abc']
>>> ret = re.findall('abc??', 'abccccccddef')
>>> print(ret)
['ab']
>>> ret = re.findall('abc{1,6}?', 'abdxxabcdxxabccdxxabcccdxxabccccdxxabccccccdxxabccccccccdxxx')
>>> print(ret)
['abc', 'abc', 'abc', 'abc', 'abc', 'abc']
9. 元字符之字符集 []
[]
表示匹配其中的任意一个字符,即或的关系。并且只能匹配到其中的一个字符。在字符集中有功能的符号有 -, ^, \
。-
表示一个范围,如 [0-9], [a-z]
;^
表示 取非,如 [^xy], [^a-z]
;\
表示转义。
>>> ret = re.findall('x[y,z]m', 'xymxxxzmxxx,mxxxmmmxx')
>>> print(ret)
['xym', 'xzm', 'x,m']
>>> ret = re.findall('x[y*z]m', 'xymxxxzmxxx*mxxxyymxx') # * 只是一个字符
>>> print(ret)
['xym', 'xzm', 'x*m']# -: 表示范围
>>> ret = re.findall('q[a-z]', 'q7xxqyzxx') # 只能匹配其中一个字符
>>> print(ret)
['qy']
>>> ret = re.findall('q[a-z]*', 'qmannux') # 与 * 搭配使用
>>> print(ret)
['qmannux']
>>> ret = re.findall('q[a-z]*', 'qnfnakff4jfq4xxqmsd') # 与 * 搭配使用可以匹配到字符集中的 0 次
>>> print(ret)
['qnfnakff', 'q', 'qmsd']# ^: 表示取非
>>> ret = re.findall('q[^xy]m', 'qxmssq^mssqymssqdmssq9mss')
>>> print(ret)
['q^m', 'qdm', 'q9m']
>>> ret = re.findall('q[^a-z]*', 'qsjfkdj666q876xx') # 搭配 *, ^ 使用
>>> print(ret)
['q', 'q876']# \: 表示转义
>>> ret = re.findall('[\d]', '45abchx3') # \d: 表示取数字
>>> print(ret)
['4', '5', '3']
>>> ret = re.findall('\([^()]*\)', '12+(34*56-54+2*(2-1))') # 转义圆括号()
>>> print(ret)
['(2-1)']
10. 元字符之转义符 \
反斜杠( \
)后跟元字符去除特殊功能,如 \., \^, \\, \*, \(, \+, \?
等;
反斜杠( \
)后跟普通字符实现特殊的功能,如 \d
等。
\d
匹配任何十进制数;相当于类[0-9]
\D
匹配任何非数字字符;相当于类[^0-9]
\s
匹配任何空白字符;相当于类[\t\n\r\f\v]
\S
匹配任何非空白字符;相当于类[^\t\n\r\f\v]
\w
匹配任何字母数字字符;相当于类[a-zA-Z0-9]
\W
匹配任何非字母数字字符;相当于 类[^a-zA-Z0-9]
\b
匹配一个特殊字符边界,比如空格,&
,#
等
>>> ret = re.findall('I\b','I am LIST')
>>> print(ret)
[]
>>> ret = re.findall('I\\b', 'hello I am LIST')
>>> print(ret)
['I']
>>> ret = re.findall(r'I\b','I am LIST')
>>> print(ret)
['I']# 匹配字符 \b
>>> ret = re.findall('I\b','I am LISTI\bhello')
>>> print(ret)
['I\x08']
>>> ret = re.findall('I\\b','I am LISTI\bhello')
>>> print(ret)
['I', 'I']
>>> ret = re.findall('I\b',r'I am LISTI\bhello')
>>> print(ret)
[]
>>> ret = re.findall('I\\b',r'I am LISTI\bhello')
>>> print(ret)
['I', 'I']
>>> ret = re.findall('I\\\\b',r'I am LISTI\bhello')
>>> print(ret)
['I\\b']
\b
在 ASCII 码中有一定有含义,表示退格符,所以,python 中字符串中若含有类似的字符,python 解释器就会把这个字符解释成 ASCII 码中的值,不会是我们输入的字符 \
和 b
。而在字符串前面加上 r
,则表示这个字符串我们看到的是什么样子,它就是这个样子,不会把还有特殊含义的字符进行解释,即 python 解释器会将 \b
转化为 \\b
这样存储。所以,对于上面,我们输入 \b
,其实传入正则表达式函数的参数是 ASCII 码中的退格符,当我们输入 \\b
,python 解释器传给正则表达式的才是正确的 \b
,即字符 \
与 b
。而在 re 模块中,\b
具有特别的含义,不会转化为对应的 ASCII 码,\f, \\
等则会转化为对应的 ASCII 码。若传给 re 模块的是 \\b
,则经过 re 处理,最后匹配的是字符 \
和 b
。
11. 元字符之分组 ()
()
标记一个子表达式的开始和结束位置。子表达式可以获取供以后使用。要匹配这些字符,请使用 \(
和 \)
。
>>> ret = re.findall(r'(ab)+', 'abbb')
>>> print(ret)
['ab']
>>> ret = re.findall('(ab)+', 'ababababbb')
>>> print(ret)
['ab']
# 这里之所以出现的只有一个 `ab`,是因为 re 模块优先显示的是组内的匹配字符串,取消使用 ?:
# 实际它已经是贪婪匹配(如果不是,结果应该是四个 ab)
>>> ret = re.findall('(?:ab)+', 'ababababbb')
>>> print(ret)
['abababab']# (?P<name>\w+) 模式
>>> ret = re.search('(?P<id>\d{2})/(?P<name>\w{3})', '23/com45/ddd66/xxxx78jishao')
>>> print(ret)
<_sre.SRE_Match object; span=(0, 6), match='23/com'>
>>> print(ret.group())
23/com
>>> print(ret.group('id'))
23
>>> print(ret.group('name'))
com
>>> ret = re.findall('(?P<id>\d{2})/(?P<name>\w{3})', '23/com45/ddd66/xxxx78jishao')
>>> print(ret)
[('23', 'com'), ('45', 'ddd'), ('66', 'xxx')]
12. 元字符之 |
|
表示两项之间的一个选择。要匹配 |
,请使用 \|
。
>>> ret = re.findall('ab|\d', 'rabhdg8sdauubuu888xdd')
>>> print(ret)
['ab', '8', '8', '8', '8']
>>> ret = re.search('ab|\d', 'rabhdg8sdauubuu888xdd')
>>> print(ret.group())
ab
13. 运算符优先级
运算符 | 描述 |
---|---|
\
|
转义符 |
(), (?:), (?=), []
|
圆括号和方括号 |
*, +, ?, {n}, {n,}, {n,m}
|
限定符 |
^, $, \ 任何元字符、任何字符
|
定位点和序列(即:位置和顺序) |
|
|
替换,"或"操作 字符具有高于替换运算符的优先级,使得"m|food"匹配"m"或"food"。若要匹配"mood"或"food",请使用括号创建子表达式,从而产生"(m|f)ood"。 |
方法
re.findall('a', 'alvin yuan')
: 返回所有满足匹配条件的结果,放在列表里re.search('a', 'alvin yuan')
: 函数会在字符串内查找模糊匹配,只找到第一个匹配然后返回一个包含匹配信息的对象,该对象可以通过调用group()
方法得到匹配的字符串,如果字符串没有匹配,则返回None
。re.match('a', 'abc').group()
: 同search
,不过尽在字符串开头处进行匹配。re.split('[ab]', 'abcd')
: 会按a
分割得到 `和
bcd,再按
b**分别**分割得到
和
cd。所以结果是
['', '', 'cd']`。re.sub('\d', 'A', 'abcde4566fghim777xfsd', 4)
: 表示将匹配到的字符串替换成另一个字符串,最后的参数表示替换的次数。这个是将数字替换成字母A
,替换四次。不写次数的话默认全部替换。结果是'abcdeAAAAfghim777xfsd'
。re.subn('\d', 'A', 'abcde4566fghim777xfsd')
: 与sub
相同,只是它返回的是一个元组,第一个是替换之后的结果,第二个是替换 的次数,不是总的可以匹配到的次数。结果是('abcdeAAAAfghimAAAxfsd', 7)
。re.subn('\d', 'A', 'abcde4566fghim777xfsd', 4)
的结果是('abcdeAAAAfghim777xfsd', 4)
。obj = re.compile('\d{3}')
: 参数只有一个,是匹配规则。函数作用是将规则进行编译,然后可以用得到的对象匹配字符串。例如:obj.findall('abc1234566ef')
,结果是['123', '456']
。对于匹配多次的规则而言,它具有更高的效率。ret = re.finditer('\d','abc345ujf789dxx')
: 将匹配到的结果用一个迭代器返回。查看方法:next(ret)
结果是<_sre.SRE_Match object; span=(3, 4), match='3'>
,查看内容使用next(ret).group()
,结果是'3'
。可以使用for
查看。
注意:
对于分组的规则匹配,默认优先返回组内的内容,若要取消,可以使用 ?:
。
>>> ret = re.findall('www\.(baidu|sina)\.com', 'www.baidu.comxxxxdddwww.sina.comddwwwxbaidu.commm')
>>> print(ret)
['baidu', 'sina']
>>> ret = re.findall('www\.(?:baidu|sina)\.com', 'www.baidu.comxxxxdddwww.sina.comddwwwxbaidu.commm')
>>> print(ret)
['www.baidu.com', 'www.sina.com']
转载于:https://www.cnblogs.com/arelive/p/python-38.html
lesson 038 —— re 模块相关推荐
- Lesson 028 —— python 模块
Lesson 028 -- python 模块 在前面的几个章节中我们脚本上是用 python 解释器来编程,如果你从 Python 解释器退出再进入,那么你定义的所有的方法和变量就都消失了. 为此 ...
- Moodle插件开发——Blocks(版块)
前提: 1) 基于Moodle3.0,要求Moodle版本高于2.0 2) PHP编程基础:语言的了解和开发工具使用 有经验的开发人员和那些只是想程序员的参考文本应参阅附录A. 1. ...
- 038医疗项目-模块四:采购单模块—采购单数据模型
上一篇文章我们知道了采购的需求.这篇文章我们就要看一下采购单模块的数据库怎么去建立. 我们设计时采用两张表: 1:采购单基本信息表(YYCGD): 也就是对应的页面上的: 当然我们设计数据库的时候不可 ...
- 未能加载指定的模块“\Neo4j-Management.psd1
未能加载指定的模块"\Neo4j-Management.psd1 解决方案 方法一 增加环境变量PSScriptRoot = "D:\beforeInstalling\neo4j- ...
- 通过PEB获取模块基址
TEB偏移0x30处,即FS:[0x30]地址处保存着一个指针,指向PEB,PEB结构的偏移0xC处保存着另外一个指针ldr,该指针执行PEB_LDR_DATA PEB结构 typedef struc ...
- python自动测试p-Python实践60-性能调优之pstats模块
cProfile生成二进制结果文件 cProfile模块提供一个功能,可以将profile结果保存为二进制文件 通过cProfile命令行生成二进制结果文件: python -m cProfile - ...
- Lesson 008 —— python 初识
Lesson 008 -- python 初识 python 文件 python 文件名 Python 文件名的后缀可以是任意的,但是,之后导入我们的模块的时候,如果文件后缀名不是 .py ,那么会报 ...
- Lesson 15.2 学习率调度在PyTorch中的实现方法
Lesson 15.2 学习率调度在PyTorch中的实现方法 学习率调度作为模型优化的重要方法,也集成在了PyTorch的optim模块中.我们可以通过下述代码将学习率调度模块进行导入. fro ...
- Lesson 13.3 梯度不平稳性与Glorot条件
Lesson 13.3 梯度不平稳性与Glorot条件 从本节开始,将正式进入到优化方法的具体方法部分内容.首先是关于激活函数使用过程的优化.在上一节的结尾,我们发现,尽管激活函数的使用能够有效提 ...
- Lesson 13.2 模型拟合度概念介绍与欠拟合模型的结构调整策略
一.模型拟合度概念介绍与实验 1.测试集的"不可知"悖论 通过此前课程内容介绍,我们已经知道了机器学习模型主要通过模型在测试集上的运行效果来判断模型好坏,测试集相当于是&quo ...
最新文章
- VTK:可视化算法之Office
- HDU1530 最大流问题
- 为什么python最后一个元素下标是负一_Python负下标
- [转]解决2003不支持FLV的方法
- mybatis中的#{}与${}在原理上的区别
- 用DELPHI为ASP开发文件上载组件
- hdfs中与file数组类似的数组_Java中的数组
- 百科知识 scm文件如何打开
- OpenWRT软件安装教程,安装的几种方法
- Stop Staring: Facial Modeling and Animation Done Right
- SCRATCH编程与科学——简单电路
- 计算机毕业设计Android手机微博系统客户端app(源码+系统+mysql数据库+Lw文档)
- Word中怎么打分段函数?
- R语言数据整理Data Tidying(基于tidyr包)
- iOS 2015年3月苹果新的审核标准(中文)
- jQuery选择器中的通配符[id*='id']及jquery选择器总结
- 为什么在浏览器中不能使用搜狗输入法,而其他地方是可以的
- World Streamer学习1
- C51中intrins_h头文件解释分析
- 原生JS仿写手机指南针(带水平仪)