Python 学习笔记 - 正则表达式模块

简介:

在Python里面,处理字符串除了基本的split,格式化操作等等,还可以使用正则表达式。使用正则表达式,需要导入模块re。正则本身也是一门语言,像下围棋一样,入门很容易,不过要玩的很溜就得花时间了。


老实说,老男孩13期的正则表达式的视频真的很烂,那个讲课的估计是个新人,说话颠三倒四,逻辑混乱,豆子听完还是稀里糊涂。


课后在网上找到一篇强文

http://www.cnblogs.com/huxi/archive/2010/07/04/1771073.html


拜读之后,受益匪浅。


基本规则如下所示:

wKioL1fWmZDyqQSPAAJ4eW9k7oo739.png


re模块有下面几个常用的函数


1. findall(pattern, string, flags=0),这个函数会返回一个列表,列表的元素是匹配到的字符串


例1,下面会匹配出以a开头的所有单词,\w+表示一个或者多个字母数字或者下划线,因为不包括空格,所以相当于单个的单词了

1
2
3
4
>>>  import  re
ret = re.findall( 'a\w+' , 'abc aaa bbh kjk hkk add' )
print (ret)
[ 'abc' 'aaa' 'add' ]


例2,在字符集里面的元素可以表示或的意义。字符集里面特殊的字符会失去意义;但是他本身有2个特殊的字符,-表示范围,^表示取反,比如说我需要查找加减乘除的符号,那么-因为有特殊含义,因此需要用转移符\转义

1
2
3
4
>>>  import  re
a = re.findall( '[+\-*/]\d' , '3+3-2*4/2' )
print (a)
[ '+3' '-2' '*4' '/2' ]



2. search(pattern,string,flags)会通过pattern去匹配,如果匹配成功,会返回一个match对象,否则返回None。然后可以通过group()函数获取对象里面的字符串


例3

1
2
3
4
5
6
>>>  import  re
obj  =  re.search( '\d+' '123uuasf' )
if  obj:
     print (obj.group())
- - - - - - - - - - - - -
123


3. match(pattern,string,flags)会通过pattern去匹配,如果匹配成功,会返回一个match对象,否则返回None。然后可以通过group()函数获取对象里面的字符串。他和search的区别在于match只能匹配字符串开头的字符,后面的无法匹配;而search可以匹配到任意位置的字符串。


例4

1
2
3
4
5
6
import  re
obj  =  re.match( '\d+' 'u123uu888asf' )
if  obj:
     print (obj.group())
- - - - - - - - - - - - -
123


4.finditer(pattern,string,flags) 搜索string,返回一个顺序访问每一个匹配结果(Match对象)的迭代器。 


例5,我希望匹配一个括号内的四则运算


注意他们的区别,search和match都返回了match对象,然后可以通过group获取字符串;而findall返回的是列表,因为我使用了圆括号分组,因此他会返回圆括号里面的内容;如何获取所有的内容呢,可以通过 finditer,他相当于一个加强版的search,会找到所有match对象放入一个列表,我们可以循环这个列表然后获取每个元素的group内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
>>> a = re.match( '\(([+\-*/]?\d+\.?\d*){1,}\)' , '(-3.2)-2*2+(2-3*(22-3*3))' )
print (a.group())
print ( 'search' .center( 40 , '-' ))
a = re.search( '\(([+\-*/]?\d+\.?\d*){1,}\)' , '2-(3*(2.2-3*3))' )
print (a.group())
print ( 'findall' .center( 40 , '-' ))
a = re.findall( '\(([+\-*/]?\d+\.?\d*){1,}\)' , '(-3.2)-2*2+(2-3*(22-3*3))' )
for  item  in  a:
     print (item)
print ( 'finditer' .center( 40 , '-' ))
a = re.finditer( '\(([+\-*/]?\d+\.?\d*){1,}\)' , '(-3.2)-2*2+(2-3*(22-3*3))' )
for  item  in  a:
     print (item.group())
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
( - 3.2 )
- - - - - - - - - - - - - - - - - search - - - - - - - - - - - - - - - - -
( 2.2 - 3 * 3 )
- - - - - - - - - - - - - - - - findall - - - - - - - - - - - - - - - - -
- 3.2
* 3
- - - - - - - - - - - - - - - - finditer - - - - - - - - - - - - - - - -
( - 3.2 )
( 22 - 3 * 3 )


5.sub(pattern, repl, string, count=0, flags=0)

用于替换匹配的字符串


例6 替换2次

1
2
3
>>> ss = 'one,two,three'
print (re.sub( '\w+' , 'AAA' ,ss, 2 ))
AAA,AAA,three


6.split(pattern, string, maxsplit=0, flags=0)


1
2
3
4
>>> a = 'i am ha happy man'
print (re.split( 'am' ,a))
- - - - - - - - - - - - - - - - -
[ 'i ' ' ha happy man' ]


除了上面的基本使用之外,还有几点需要注意。


*转移符\的使用,Python本身有转移符,在Re模块中也有转移符,因此,如果在Re里要匹配一个字符\,需要使用\\\\四次,首先Python转移为\\进入Re,然后Re再转义成\;一个简单的方法是使用原生字符r,这样\\就行了。


例7

1
2
3
4
5
6
>>> a = re.findall( '\\\\',' \sabc')
print (a)
b = re.findall(r '\\',' \sjkll')
print (b)
[ '\\' ]
[ '\\' ]


正则里面有1个基本的概念叫做贪婪模式和懒惰模式。在上面的例子里面,默认都是使用的贪婪模式,如果一个字符串里面存在多个匹配,他默认用最长的那个;懒惰模式则是对应的最短的那个匹配。懒惰模式可以通过*?或者+?或者 ??来实现。注意单独使用的?表示前面那个字符的0或者1次匹配,但是组合在一起就是懒惰模式了。


例8,这里 .*? 相当于一个整体,.*表示任意值,而.*?表示任意值的懒惰匹配

1
2
3
4
5
6
7
8
9
10
11
12
13
import  re
s1 = "hello Pythonssn"
pat = "p.*n"
pat2 = "p.*?n"
r1 = re.search(pat,s1,re.I)
r2 = re.search(pat2,s1,re.I)
if  r1:
     print (r1.group())
if  r2:
     print (r2.group())
  - - - - - - - - -
Pythonssn
Python


第二个重要的概念是模式修饰符,可以在不修改模式的情况下实现一些额外的功能,常见的比如可以进行多行匹配,忽略大小写和用. 来替代换行符


例9

1
2
3
4
5
6
7
8
9
10
11
12
s2 = """
python is funny,
Python is not PPython;
ppyhonn is Pyyon
"""
pat3 = "p.*?n"
pat4 = "p.*n"
r = re.findall(pat3,s2,re.I|re.M)
r2 = re.findall(pat4,s2,re.I)
- - - - - - -
[ 'python' 'Python' 'PPython' 'ppyhon' 'Pyyon' ]
[ 'python is funn' 'Python is not PPython' 'ppyhonn is Pyyon' ]


正则里面还有有一个概念叫做分组。简单的说,分组就是在已经匹配获取的结果里面继续划分新的子集。


在search和match里面,group代表的是获取通过pattern匹配出来的结果;groups表示分组之后的结果;groupdic同样表示分组之后的结果,不过他需要通过P?指定名字才能显示出来


例10

1
2
3
4
5
6
7
8
9
import  re
a = re.search( 'h(?P<name>\w+)' , 'hello 123a hoo bc333' )
print (a.group())
print (a.groups())
print (a.groupdict())
- - - - - - - - - - - - - - - -
hello
( 'ello' ,)
{ 'name' 'ello' }


在findall里面分组比较特殊,如果有分组,那么他直接就显示出分组之后的子集,而不是匹配到的字符串


例9 首先匹配到['1hh','2kll']然后分组获取数字后面部分

1
2
3
4
>>>  import  re
a = re.findall( '\d(\w+)' , '1hh jjkl2 hhs 2kll' )
print (a)
[ 'hh' 'kll' ]


sub就是替换,不存在分组


split的分组如下所示


例11,对比一下不分组和分组的差别,前者分割之后不会出现分隔符,后者会显示出来

1
2
3
4
5
6
7
>>> a = 'i am ha happy man'
print (re.split( 'am' ,a))
a = 'i am ha happy man'
print (re.split( '(am)' ,a))
- - - - - - - - - - - - - - - -
[ 'i ' ' ha happy man' ]
[ 'i ' 'am' ' ha happy man' ]


最后补充一下,正则表达式的函数除了可以直接使用re.search, re.match等形式,还可以先编译一个pattern,然后通过pattern来调用这些函数


例12 先编译一次正则表达式,然后再通过编译后的pattern来调用,这样如果调用的地方很多,可以节省一下资源

1
2
3
4
5
6
7
>>>  import  re
>>> p = re. compile (r '\b\w+\b' )
>>> match = p.search( 'jkl jkljl 23jk4 kjl2' )
>>>  print (match.group())
jkl
>>> p.findall( 'jkl kls 234lkjk23 23lk ' )
[ 'jkl' 'kls' '234lkjk23' '23lk' ]





本文转自 beanxyz 51CTO博客,原文链接:http://blog.51cto.com/beanxyz/1852180,如需转载请自行联系原作者

目录
相关文章
|
21天前
|
存储 开发者 Python
Python中的collections模块与UserDict:用户自定义字典详解
【4月更文挑战第2天】在Python中,`collections.UserDict`是用于创建自定义字典行为的基类,它提供了一个可扩展的接口。通过继承`UserDict`,可以轻松添加或修改字典功能,如在`__init__`和`__setitem__`等方法中插入自定义逻辑。使用`UserDict`有助于保持代码可读性和可维护性,而不是直接继承内置的`dict`。例如,可以创建一个`LoggingDict`类,在设置键值对时记录操作。这样,开发者可以根据具体需求定制字典行为,同时保持对字典内部管理的抽象。
|
24天前
|
存储 C语言 Python
【Python】学习笔记day3
【Python】学习笔记day3
27 1
|
23天前
|
存储 缓存 算法
Python中collections模块的deque双端队列:深入解析与应用
在Python的`collections`模块中,`deque`(双端队列)是一个线程安全、快速添加和删除元素的双端队列数据类型。它支持从队列的两端添加和弹出元素,提供了比列表更高的效率,特别是在处理大型数据集时。本文将详细解析`deque`的原理、使用方法以及它在各种场景中的应用。
|
3天前
|
数据挖掘 API 数据安全/隐私保护
python请求模块requests如何添加代理ip
python请求模块requests如何添加代理ip
|
5天前
|
测试技术 Python
Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘
Python 有趣的模块之pynupt——通过pynput控制鼠标和键盘
|
5天前
|
Serverless 开发者 Python
《Python 简易速速上手小册》第3章:Python 的函数和模块(2024 最新版)
《Python 简易速速上手小册》第3章:Python 的函数和模块(2024 最新版)
37 1
|
6天前
|
Python
基于Django的Python应用—学习笔记—功能完善
基于Django的Python应用—学习笔记—功能完善
|
7天前
|
Python
python学习-函数模块,数据结构,字符串和列表(下)
python学习-函数模块,数据结构,字符串和列表
47 0
|
8天前
|
Python
python学习14-模块与包
python学习14-模块与包
|
10天前
|
SQL 关系型数据库 数据库
Python中SQLite数据库操作详解:利用sqlite3模块
【4月更文挑战第13天】在Python编程中,SQLite数据库是一个轻量级的关系型数据库管理系统,它包含在一个单一的文件内,不需要一个单独的服务器进程或操作系统级别的配置。由于其简单易用和高效性,SQLite经常作为应用程序的本地数据库解决方案。Python的内置sqlite3模块提供了与SQLite数据库交互的接口,使得在Python中操作SQLite数据库变得非常容易。

热门文章

最新文章