详解Python中的正则表达式


Posted in Python onJuly 08, 2018

一、正则表达式简介

正则表达式是一个特殊的字符序列,它能帮助你方便的检查一个字符串是否与某种模式匹配。 Python 自1.5版本起增加了re 模块,它提供 Perl 风格的正则表达式模式。

就其本质而言,正则表达式(或 RE)是一种小型的、高度专业化的编程语言, (在Python中)它内嵌在Python中,并通过 re 模块实现。正则表达式模式被 编译成一系列的字节码,然后由用 C 编写的匹配引擎执行。

re 模块使 Python 语言拥有全部的正则表达式功能。 compile 函数根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。 re 模块也提供了与这些方法功能完全一致的函数,这些函数使用一个模式字符串做为它们的第一个参数。 

二、字符匹配

1.普通字符:大多数字符和字母都会和自身匹配

>>> re.findall("alexsel","gtuanalesxalexselericapp")
['alexsel']
>>> re.findall("alexsel","gtuanalesxalexswxericapp")
[]
>>> re.findall("alexsel","gtuanalesxalexselwupeiqialexsel")
['alexsel', 'alexsel']

2.元字符: .   ^   $   *   +   ?   { }   [ ]   |   ( )  \

•.   :匹配一个除了换行符任意一个字符

>>> re.findall("alexsel.w","aaaalexselaw")
['alexselaw']
#一个点只能匹配一个字符

•^  :只有后面跟的字符串在开头,才能匹配上

>>> re.findall("^alexsel","gtuanalesxalexselgeappalexsel")
[]
>>> re.findall("^alexsel","alexselgtuanalesxalexselwgtappqialexsel")
['alexsel']
#"^"这个符号控制开头,所以写在开头

•$  :只有它前面的字符串在检测的字符串的最后,才能匹配上

>>> re.findall("alexsel$","alexselseguanalesxalexselganapp")
[]
>>> re.findall("alexsel$","alexselgtaanalesxalexsssiqialexsel")
['alexsel']

•*  :它控制它前面那个字符,他前面那个字符出现0到多个都可以匹配上

>>> re.findall("alexsel*","aaaalexse")
['alexse']
>>> re.findall("alexsel*","aaaalexsel")
['alexsel']
>>> re.findall("alex*","aaaalexsellllll")
['alexsellllll']

•+ :匹配前面那个字符1到多次

>>> re.findall("alexsel+","aaaalexselll")
['aleselll']
>>> re.findall("alexsel+","aaaalexsel")
['alexsel']
>>> re.findall("alexsel+","aaaalexse")
[]

•? :匹配前面那个字符0到1个,多余的只匹配一个

>>> re.findall("alexsel?","aaaalexse")
['ale']
>>> re.findall("alexsel?","aaaalexsel")
['alexsel']
>>> re.findall("alexsel?","aaaalexsellll")
['alexsel']

•{}  :控制它前面一个字符的匹配个数,可以有区间(闭区间),有区间的情况下按照多的匹配

>>> re.findall("alexsel{3}","aaaalexselllll")
['alexselll']
>>> re.findall("alexsel{3}","aaaalexsell")
[]
>>> re.findall("alexsel{3}","aaaalexse")
[]
>>> re.findall("alexsel{3}","aaaalexselll")
['alexselll']
>>> re.findall("alexsel{3,5}","aaaalexsellllllll")
['alexselllll']
>>> re.findall("alexsel{3,5}","aaaalexselll")
['alexselll']
>>> re.findall("alexsel{3,5}","aaaalexsell")
[]

•\  :

后面跟元字符去除特殊功能,
 

后面跟普通字符实现特殊功能。
 

引用序号对应的字组所匹配的字符串 (一个括号为一个组)。

在开头加上 r 表示不转义。

#\2 就相当于第二个组(eric)
>>> re.search(r"(alexsel)(eric)com\2","alexselericcomeric").group()
'alexselericcomeric'
>>> re.search(r"(alexsel)(eric)com\1","alexselericcomalex").group()
'alexselericcomalex'
>>> re.search(r"(alexsel)(eric)com\1\2","alexselericcomalexseleric").group()
'alexselericcomalexeric'

\d  :匹配任何十进制数;它相当于类[0-9]

>>> re.findall("\d","aaazz1111344444c")
['1', '1', '1', '1', '3', '4', '4', '4', '4', '4']
>>> re.findall("\d\d","aaazz1111344444c")
['11', '11', '34', '44', '44']
>>> re.findall("\d0","aaazz1111344444c")
[]
>>> re.findall("\d3","aaazz1111344444c")
['13']
>>> re.findall("\d4","aaazz1111344444c")
['34', '44', '44']

\D  :匹配任何非数字字符;它相当于类[^0-9]

>>> re.findall("\D","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', 'c']
>>> re.findall("\D\D","aaazz1111344444c")
['aa', 'az']
>>> re.findall("\D\d\D","aaazz1111344444c")
[]
>>> re.findall("\D\d\D","aaazz1z111344444c")
['z1z']

\s  :匹配任何空白字符;它相当于类[ \t\n\r\f\v]

>>> re.findall("\s","aazz1 z11..34c")
[' ']

\S  :匹配任何非空白字符;它相当于类[^ \t\n\r\f\v]

\w  :匹配任何字母数字字符;他相当于类[a-zA-Z0-9_]

>>> re.findall("\w","aazz1z11..34c")
['a', 'a', 'z', 'z', '1', 'z', '1', '1', '3', '4', 'c']

\W  :匹配任何非字母数字字符;它相当于类[^a-zA-Z0-9_]

\b  :匹配一个单词边界,也就是指单词和空格间的位置

>>> re.findall(r"\babc\b","abc sdsadasabcasdsadasdabcasdsa")
['abc']
>>> re.findall(r"\balexsel\b","abc alexsel abcasdsadasdabcasdsa")
['alexsel']
>>> re.findall("\\balexsel\\b","abc alexsel abcasdsadasdabcasdsa")
['alexsel']
>>> re.findall("\balexsel\b","abc alexsel abcasdsadasdabcasdsa")
[]

 

()  :把括号内字符作为一个整体去处理

>>> re.search(r"a(\d+)","a222bz1144c").group()
'a222'
>>> re.findall("(ab)*","aabz1144c")
['', 'ab', '', '', '', '', '', '', ''] #将括号里的字符串作为整和后面字符逐个进行匹配,在这里就首先将后面字符串里的a和ab进
#行匹配,开头匹配成功,在看看后面是a,和ab中的第二个不匹配,然后就看后面字符串中的第二个a,和ab匹配,首先a匹配成功,b也匹配成功,拿到匹配
#然后在看后面字符串中的第三个是b,开头匹配失败,到第四个,后面依次
>>> re.search(r"a(\d+)","a222bz1144c").group()
'a222'
>>> re.search(r"a(\d+?)","a222bz1144c").group() +的最小次数为1
'a2'
>>> re.search(r"a(\d*?)","a222bz1144c").group() *的最小次数为0
'a'
#非贪婪匹配模式 加? ,但是如果后面还有匹配字符,就无法实现非贪婪匹配
#(如果前后均有匹配条件,则无法实现非贪婪模式)
>>> re.findall(r"a(\d+?)b","aa2017666bz1144c")
['2017666']
>>> re.search(r"a(\d*?)b","a222bz1144c").group()
'a222b'
>>> re.search(r"a(\d+?)b","a277722bz1144c").group()
'a277722b'

 元字符在字符集里就代表字符,没有特殊意义(有几个例外)

>>> re.findall("a[.]d","aaaacd")
[]
>>> re.findall("a[.]d","aaaa.d")
['a.d']

例外
[-] [^] [\]

[-]

#匹配单个字符,a到z所有的字符
>>> re.findall("[a-z]","aaaa.d")
['a', 'a', 'a', 'a', 'd']
>>> re.findall("[a-z]","aaazzzzzaaccc")
['a', 'a', 'a', 'z', 'z', 'z', 'z', 'z', 'a', 'a', 'c', 'c', 'c']
>>>
>>> re.findall("[1-3]","aaazz1111344444c")
['1', '1', '1', '1', '3']
[^]
#匹配除了这个范围里的字符,(^在这里有 非 的意思)
>>> re.findall("[^1-3]","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', '4', '4', '4', '4', '4', 'c']
>>> re.findall("[^1-4]","aaazz1111344444c")
['a', 'a', 'a', 'z', 'z', 'c']
[\]
>>> re.findall("[\d]","aazz1144c")
['1', '1', '4', '4']

我们首先考察的元字符是"[" 和 "]"。它们常用来指定一个字符类别,所谓字符类 别就是你想匹配的一个字符集。字符可以单个列出,也可以用“-”号分隔的两个给定 字符来表示一个字符区间。例如,[abc] 将匹配"a", "b", 或 "c"中的任意一个字 符;也可以用区间[a-c]来表示同一字符集,和前者效果一致。如果你只想匹配小写 字母,那么 RE 应写成 [a-z],元字符在类别里并不起作用。例如,[akm$]将匹配字符"a", "k", "m", 或 "$" 中 的任意一个;"$"通常用作元字符,但在字符类别里,其特性被除去,恢复成普通字符。

三、Python正则表达式各种函数以及参数解析

match: re.match(pattern,string,flags=0)

flags 编译标志位,用于修改正则表达式的匹配方式,如:是否区别大小写

re.match("com","comwww.runcomoob").group()
'com'
re.match("com","Comwww.runComoob",re.I).group()
'Com'

flags 编译标志位

re.I 使匹配对大小写不敏感

>>> re.search("com","COM",re.I).group()
  'COM'

re.L 做本地化识别(locale-aware)匹配

re.M 多行匹配,影响^和$

re.S 使.匹配包括换行在内的所有字符

>>> re.findall(".","abc\nde")
['a', 'b', 'c', 'd', 'e']
>>> re.findall(".","abc\nde",re.S)
['a', 'b', 'c', '\n', 'd', 'e']

re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B

re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

search:re.search(pattern,string,flags=0)

re.search("\dcom","www.4comrunoob.5com").group()
'4com'

re.match与re.search的区别

re.match只匹配字符串的开始,如果字符串开始不符合正则表达式,则匹配失败,函数返回None;而re.search匹配整个字符串,直到找到一个匹配。

match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:
•group()

返回被RE匹配的字符串
•start()

    返回匹配开始的位置
•end()

     返回匹配结束的位置
•span()

   返回一个元组包含匹配(开始,结束)的位置
•group()

返回re整体匹配的字符串,可以一次输入多个组号,对应组号匹配的字符串,获取匹配到的所有结果(无论是否有组)
•a. group ()  返回re整体匹配的字符串,
•b. group (n,m) 

返回组号为n,m所匹配的字符串,如果组号不存在,则返回indexError异常
•c. groups()

groups() 方法返回一个包含正则表达式中所有小组字符串的元组,从 1 到所含的小组号,通常groups()不需要参数,返回一个元组,元组中的元就是正则表达式中定义的组。
a = "123abc456"
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(0)   #123abc456,返回整体
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(1)   #123
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(2)   #abc
re.search("([0-9]*)([a-z]*)([0-9]*)",a).group(3)   #456

在上面的代码练习中,我们看到很多代码后面加有group,在这我们就针对这个group进行解析。

m = re.match("([abc])+", "abc")

一般,m.group(N) 返回第N组括号匹配的字符。 而m.group() == m.group(0) == 所有匹配的字符,与括号无关,这个是API规定的。 m.groups() 返回所有括号匹配的字符,以tuple格式。m.groups() == (m.group(0), m.group(1), ...)

sub subn:

re.sub(pattern, repl, string, max=0)

>>> re.sub("g.t","have","I get A, I got B, I gut C")#匹配g.t字符,用have替换(.匹配一个除了换行符任意一个字符)
'I have A, I have B, I have C'
>>> re.sub("got","have","I get A, I got B, I gut C")
'I get A, I have B, I gut C'
>>> re.sub("g.t","have","I get A, I got B, I gut C",2)#替换两个
'I have A, I have B, I gut C'
>>> re.sub("g.t","have","I get A, I got B, I gut C",1)
'I have A, I got B, I gut C'
>>> re.subn("g.t","have","I get A, I got B, I gut C")#使用re.subn显示替换里多少个
('I have A, I have B, I have C', 3)

re.compile(strPattern[, flag]):

这个方法是Pattern类的工厂方法,用于将字符串形式的正则表达式编译为Pattern对象。

第二个参数flag是 匹配模式,取值可以使用按位或运算符‘|‘表示同时生效,比如re.I | re.M可以把正则表达式编译成一个正则表达式对象。可以把那些经常使用的正则表达式编译成正则表达式对象,这样可以提高一定的效率。

一个正则表达式对象的一个例子:

>>> text = "JGood is a handsome boy, he is cool, clever, and so on..."
>>> regex = re.compile(r"\w*oo\w*")
>>> print regex.findall(text)
['JGood', 'cool']

split:

p = re.compile(r"\d+")    #+:匹配前面那个字符1到多次
p.split("one1two2three3four4")    #spilt分割
>>> p = re.compile(r"\d+")
>>> p.split("one1two2three3four4")
['one', 'two', 'three', 'four', '']
re.split("\d+","one1two2three3four4")
>>> re.split("\d+","one1two2three3four4")
['one', 'two', 'three', 'four', '']
>>> re.split("\d+","4one1two2three3four4")
['', 'one', 'two', 'three', 'four', '']#如果分割时左边或者右边已经被分过
>>> re.split("[bc]","abcd")#或者是无字符的情况下,就分出一个空字符
['a', '', 'd']

finditer():

>>> p = re.compile(r"\d+")
>>> iterator = p.finditer("12 drumm44ers drumming, 11 ... 10 ...")
>>>
>>> iterator
<callable-iterator object at 0x02626990>
>>> for match in iterator:
...   match.group() , match.span()#每个数字以及它们出现的位置
...
('12', (0, 2))
('44', (8, 10))
('11', (24, 26))
('10', (31, 33))

由于我们是在python下使用的正则表达式,所以特殊字符需要多次转意,而使用了rawstring之后,就不用在多次转意仅仅就使用正则的规则就可以。

>>> re.findall(r"\d","www4dd6")
['4', '6']
>>> re.findall("\\d","www4dd6")
['4', '6']
>>> re.findall("\d","www4dd6")
['4', '6']
#在这里\d成功的原因是因为\d在ascii码中没有特殊含义,所以在这里就自动转意了,不过正规的写法就是前两个

单词边界

>>> re.findall(r"\babc","abcsd abc")
['abc', 'abc']
>>> re.findall(r"abc\b","abcsd abc")
['abc']
>>> re.findall(r"abc\b","abcsd abc*")
['abc']
>>> re.findall(r"\babc","*abcsd*abc")
['abc', 'abc']
#检测单词边界不一定就是空格,还可以是除了字母以外的特殊字符

总结

以上所述是小编给大家介绍的Python中的正则表达式 ,希望对大家有所帮助,如果大家有任何疑问欢迎给我留言,小编会及时回复大家的!

Python 相关文章推荐
python转换字符串为摩尔斯电码的方法
Jul 06 Python
使用Python保存网页上的图片或者保存页面为截图
Mar 05 Python
Python检测网站链接是否已存在
Apr 07 Python
python matplotlib 在指定的两个点之间连线方法
May 25 Python
Python实现连接MySql数据库及增删改查操作详解
Apr 16 Python
详解python解压压缩包的五种方法
Jul 05 Python
pycharm新建一个python工程步骤
Jul 16 Python
pytorch:实现简单的GAN示例(MNIST数据集)
Jan 10 Python
PyQt5中QTableWidget如何弹出菜单的示例代码
Feb 23 Python
python seaborn heatmap可视化相关性矩阵实例
Jun 03 Python
Python timeit模块原理及使用方法
Oct 10 Python
python 实现Requests发送带cookies的请求
Feb 08 Python
实例讲解Python爬取网页数据
Jul 08 #Python
python十进制和二进制的转换方法(含浮点数)
Jul 07 #Python
Python3+django2.0+apache2+ubuntu14部署网站上线的方法
Jul 07 #Python
python3实现字符串的全排列的方法(无重复字符)
Jul 07 #Python
python3 kmp 字符串匹配的方法
Jul 07 #Python
vue.js实现输入框输入值内容实时响应变化示例
Jul 07 #Python
详解Python最长公共子串和最长公共子序列的实现
Jul 07 #Python
You might like
php之header的不同用法总结(实例讲解)
2017/11/28 PHP
laravel-admin 中列表筛选方法
2019/10/03 PHP
JS在IE和FF下attachEvent,addEventListener学习笔记
2009/11/26 Javascript
jquery的冒泡事件的阻止与允许(三种实现方法)
2013/02/01 Javascript
输入框过滤非数字的js代码
2014/09/18 Javascript
JS获取时间的方法
2015/01/21 Javascript
JavaScript中用sort()方法对数组元素进行排序的操作
2015/06/09 Javascript
js实现汉字排序的方法
2015/07/23 Javascript
JavaScript缓冲运动实现方法(2则示例)
2016/01/08 Javascript
微信小程序加载更多 点击查看更多
2016/11/29 Javascript
用jQuery将JavaScript对象转换为querystring查询字符串的方法
2018/11/12 jQuery
vue 获取及修改store.js里的公共变量实例
2019/11/06 Javascript
js实现点击选项置顶动画效果
2020/08/25 Javascript
express异步函数异常捕获示例详解
2020/11/30 Javascript
Python中的数学运算操作符使用进阶
2016/06/20 Python
Python类属性的延迟计算
2016/10/22 Python
详解 Python中LEGB和闭包及装饰器
2017/08/03 Python
python 将数据保存为excel的xls格式(实例讲解)
2018/05/03 Python
pyqt5的QComboBox 使用模板的具体方法
2018/09/06 Python
详解如何管理多个Python版本和虚拟环境
2019/05/10 Python
pycharm访问mysql数据库的方法步骤
2019/06/18 Python
python命令行工具Click快速掌握
2019/07/04 Python
Django中多种重定向方法使用详解
2019/07/17 Python
Pytorch 搭建分类回归神经网络并用GPU进行加速的例子
2020/01/09 Python
澳大利亚在线高跟鞋商店:Shoe Me
2019/11/19 全球购物
.net C#面试题
2012/08/28 面试题
护士自我鉴定范文
2013/10/06 职场文书
应届生幼儿园求职信
2013/11/12 职场文书
运动会获奖感言
2014/02/11 职场文书
奥巴马获胜演讲稿
2014/05/15 职场文书
先进事迹演讲稿
2014/09/01 职场文书
教师四风问题对照检查材料
2014/09/26 职场文书
领导班子四风查摆对照检查材料思想汇报
2014/10/05 职场文书
考试作弊万能检讨书
2014/10/19 职场文书
2015年底工作总结范文
2015/05/15 职场文书
Vue Element plus使用方法梳理
2022/12/24 Vue.js