热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Python内置模块详解:正则表达式re模块的应用与解析

正则表达式是一种强大的文本处理工具,通过特定的字符序列来定义搜索模式。本文详细介绍了Python内置的`re`模块,探讨了其在字符串匹配、验证和提取中的应用。例如,可以通过正则表达式验证电子邮件地址、电话号码、QQ号、密码、URL和IP地址等。此外,文章还深入解析了`re`模块的各种函数和方法,提供了丰富的示例代码,帮助读者更好地理解和使用这一工具。

13.python内置模块之re模块

什么是正则?

正则表达式也称为正则,是一个特殊的字符序列,能帮助检查一个字符串是否与某种模式匹配。可以用来进行验证:邮箱、手机号、qq号、密码、url = 网站地址、ip等。正则不是python语言独有的技术,python语言直到1.5版本才将正则表达式完成的整理/纳入进re模块中,我们只需要导入re模块,然后就可以使用其中所有和正则相关的函数和属性了。

 

1. re模块中最常用的几个函数

1). re.match函数:

    功能:将string数据从头开始尝试匹配 ;如果匹配成功,那么就会返回给程序一个match对象;如果开头就不匹配,那么直接返回None值;

    语法格式:re.match(regex, string[, flags=0])

    参数:regex:匹配的正则表达式(内部定义了一套验证规则)

               string:需要被验证的字符串数据

               flags:可选参,模式/标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。默认情况下(不显示定义) --> 不开启任何的模式

【注意】匹配成功re.match方法返回一个匹配的对象,否则返回None。我们可以使用group(num) 或 groups() 等匹配对象函数来获取匹配表达式。match对象有5个常用的函数:

           (1). group():返回匹配成功的数据值(理解:原串中的某部分子串信息)

   (2). start():返回匹配成功的数据的起始索引

   (3). end():  返回匹配成功的数据的结束索引

   (4). span(): 返回一个元祖对象,有两个元素组成;第一个元素记录了匹配成功的数据的起始索引第二个元素记录了匹配成功的数据的结束索引

   (5). groups():以元祖的形式返回所有子组的信息(一个包含所有小组字符串的元组,从1到所含的小组号);如果没有进行正则分组,则返回一个空元祖。

 1 import re
2
3
mo = re.match(r"Www","www.baidu.com") 4 print(mo) # None 5 print(type(mo)) # 6 7 print(re.match(r"www","www.sina.com")) # <_sre.SRE_Match object; span=(0, 3), match="www"> 8 print(re.match(r"www","www.sina.com").group()) # www 9 print(re.match(r"www","www.sina.com").start()) # 0 10 print(re.match(r"www","www.sina.com").end()) # 3 11 print(re.match(r"www","www.sina.com").span()) # (0,3) 12 print(re.match(r"www","www.sina.com").groups()) # () 13 print(re.match(r"WWW","www.sina.com")) # None 14 print(re.match(r"WWW","www.sina.com",flags=re.I)) # <_sre.SRE_Match object; span=(0, 3), match="www"> 15 16 17 18 line = "Cats are smarter than dogs" 19 20 matchObj = re.match( r"(.*) are (.*?) .*", line, re.M|re.I) 21 22 if matchObj: 23 print(matchObj.group()) # "Cats are smarter than dogs" 24 print(matchObj.group(1)) # "Cats" 25 print(matchObj.group(2)) # "smarter"
26
print(matchObj.groups()) # ("Cats","smarter")
27 else:
28 print("No match!!")

 

【补充】:第二种方式实现正则对数据的校验:re.compile函数

   功能:compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。

   语法格式为:re.compile(regex[, flags])

   参数:match一样理解

【注意】compile 函数执行完毕以后返回给程序一个Pattern对象(理解:对象的内部封装了一套regexflags),可以再通过Pattern对象调用其match函数(此时的match函数只需要传递一个参数:string即可)

 

compile()配合match()使用演示:

1 import re
2 
3 pat = re.compile(r"www",flags=re.I)
4 print(pat)                          # re.compile("www", re.IGNORECASE) 
5 print(type(pat)))                     # 
6 print(pat.match("www.baidu.com"))     # <_sre.SRE_Match object; span=(0, 3), match="www">
7 
8 # 相当于 re.compile.match(r"www","www.baidu.com",flags=re.I)

【注意事项】:

    1).正则表达式返回的索引值需要满足含头不含尾的特点

    2).正则表达式验证的数据内容严格区分大小写

 3).之后在定义正则表达式的时候,在它的第一个引号前面,都显示的追加一个r,无脑行为...(转义字符)

 

2). re.search函数:

 功能:从头开始尝试匹配,如果开头就匹配不成功,不会返回None值,会继续尝试往后匹配;一旦匹配成功了,就直接返回一个match对象,后续就算还存在可以匹配成功的子串数据,也不会再匹配了(直接无视);如果直到最后都匹配不成功,返回一个None值。

   语法格式:re.search(regex,string[,flags=0])

 参数:match一样理解

【补充】:由于search函数调用返回的是match对象,所以仍然可以调用5个常用的函数

 1 import re
 2 
 3 print(re.match(r"www","hahawww.baidu.com!!www.qfedu.comhehe"))              # None
 4 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe"))             # <_sre.SRE_Match object; span=(4, 7), match="www">
 5 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe").group())     # www
 6 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe").start())     # 4
 7 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe").end())       # 7
 8 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe").span())      # (4, 7)
 9 print(re.search(r"www","hahawww.baidu.com!!www.qfedu.comhehe").groups())    # ()
10 print(re.search(r"Www","hahawww.baidu.com!!www.qfedu.comhehe"))             # None
11 print(re.search(r"Www","hahawww.baidu.com!!www.qfedu.comhehe",flags=re.I))  # <_sre.SRE_Match object; span=(4, 7), match="www">

 

compile()配合search()使用演示:

1 import re
2 
3 pat = re.compile(r"www") 
4 mo = pat.search("Wwww.sina.com!!www.baidu.com!!www") 
5 
6 print(mo)      # <_sre.SRE_Match object; span=(1, 4), match="www">

 

3). re.findall函数:

 

 功能:在字符串中找到所有匹配成功的子数据(子串),都存入到列表中返回;如果一个都匹配不成功,那么返回一个空列表

 

 语法格式:re.findall(regex,string[, pos[, endpos]][,flags=0])

 

 参数:pos:可选参数,指定字符串的起始位置,默认为 0

               endpos :可选参数,指定字符串的结束位置,默认为字符串的长度

         其他参数matchsearch一样理解

1 import re
2 
3 lt = re.findall(r"www","www.sina.com!!www.baidu.com")
4 print(lt,type(lt))        # ["www", "www"]    
5 
6 lt1 = re.findall(r"WWW","www.sina.com!!www.baidu.com!!WWW",flags=re.I)
7 print(lt1,type(lt1))      # ["www", "www", "WWW"]    
8  

 

compile()配合search()使用演示:

 1 import re
 2 
 3 pat = re.compile(r"www",flags=re.I)
 4 lt = pat.findall("www.sina.com!!www.baidu.com!!WWW")
 5  
 6 print(lt)             # ["www", "www", "WWW"]
 7 
 8 
 9  
10 pattern = re.compile(r"d+")                                # 查找数字
11 result1 = pattern.findall("runoob 123 google 456")          # 不指定字符串的起始和结束位置
12 result2 = pattern.findall("run88oob123google456", 0, 10)    # 指定字符串的起始和结束位置
13  
14 print(result1)        # ["123", "456"]
15 print(result2)        # ["88", "12"]

 

4). re.finditer函数:

 功能:和 findall 类似,在字符串中找到正则表达式所匹配的所有子串,但是将所有匹配成功的数据封装为一个一个的match对象, 然后以iterator(迭代器对象)返回

    语法格式:finditer(regex,string[,flags=0])

    参数:matchsearchfindall一样理解

 1 import re
 2 
 3 it = re.finditer("apple", "i hate apple apple apple  so much")
 4 
 5 # iterator(迭代器对象)不能直接使用内置函数len()执行查看其容量大小,会报错:TypeError; 但是可以先将其转换为容器对象(list、tuple...),就可以被len()所执行了;
 6 print(len(it))          # TypeError
 7 print(len(list(it)))    # 3
 8 
 9 # 使用遍历的思想去访问iterator中的元素
10 for i in it:
11     print(i)
12     print(type(i))
13     print(i.group())
14 
15 # <_sre.SRE_Match object; span=(7, 12), match="japan">
16 # 
17 # apple
18 
19 # <_sre.SRE_Match object; span=(13, 18), match="japan">
20 # 
21 # apple
22 
23 # <_sre.SRE_Match object; span=(19, 24), match="japan">
24 # 
25 # apple
26 
27 #迭代器对象中的内容只能被使用一次,不可逆,否则报错:StopIteration
28 # print(next(it))
29 
30 # 使用while循环来遍历iterator对象,结果和for......in..一样
31 while 1:
32     try:
33         mo = next(it)
34         print(mo)
35         print(mo.group())
36     except:
37         break

 

 

5). re.sub 函数:

   功能:替换字符数据

   语法格式:sub(regex,repl,string,[count],[flags=0])返回字符串(已经被替换完成后的内容)

                      subn(regex,repl,string,[count],[flags=0])返回元祖对象,此对象有两个元素;第一个元素记录了替换以后的字符串内容,第二个元素记录了被替换的次数(count)

 参数:regex:正则规则(字符串)

     repl:替换成的字符串内容,也可为一个函数

        string:原串数据

 

        count:次数,模式匹配后替换的最大次数,默认 为0 表示替换所有的匹配

 1 import re 
 2 
 3 str1 = re.sub("beijing", "shanghai", "i love beijing beijing beijing so much")
 4 print(str1,type(str1))       # i love shanghai shanghai shanghai so much 
 5 
 6 tp = re.subn("beijing", "shanghai", "i love beijing beijing beijing so much", 2)       # 2改成4也不会报错,就会全部替换
 7 print(tp,type(tp))           # ("i love shanghai shanghai beijing so much", 2) 
 8 
 9 
10 # 示例:模拟让游戏世界变得和谐(使用正则)
11 regex = r"CNM|MB|SB|NC|WQNMLGB|TMD|NND"
12 game = "WQNMLGB!!连装备都不会出...小学生!!SB..."
13 
14 s = re.sub(regex,"***",game)
15 print(s)      # ***!!连装备都不会出...小学生!!***...
16 
17   
18 # 示例:删除某些内容
19 phOne= "2004-959-559 # 这是一个国外电话号码"
20  
21 # 删除字符串中的Python注释 
22 num = re.sub(r"#.*$", "", phone)
23 print("电话号码是: ", num)      # 电话号码是:  2004-959-559 
24  
25 # 删除非数字(-)的字符串 
26 num = re.sub(r"D", "", phone)
27 print("电话号码是 : ", num)     # 电话号码是 :  2004959559
28 
29 
30 # 示例:repl参数是一个函数时,将字符串中的匹配的数字乘以 2
31 # 将匹配的数字乘以 2
32 def double(matched):
33     value = int(matched.group("value"))
34     return str(value * 2)
35  
36 s = "A23G4HFD567"
37 print(re.sub("(?Pd+)", double, s))    # A46G8HFD1134

【补充示例】:替换相关的操作

 1 str5 = "dsaf######32141asf#####dsafa#########()!,.___######21341##"
 2 
 3 # 将一个#替换成为一个-
 4 regex1 = r"#"    
 5 str6 = re.sub(regex1,"-",str5)
 6 print(str6)            # dsaf------32141asf-----dsafa---------()!,.___------21341--
 7 
 8 # 将一堆#替换成为一个-
 9 regex2 = r"#+"
10 tp = re.subn(regex2,"-",str5)
11 print(tp)              # ("dsaf-32141asf-dsafa-()!,.___-21341-", 5)

 

6). re.split 函数:

   功能:按照能够匹配的子串将字符串分割后返回列表

   语法格式:re.split(regex, string[, maxsplit=0, flags=0])

   参数:maxsplit :分隔次数,maxsplit=1 分隔一次,默认为 0,不限制次数

 1 import re 
 2 
 3 str1 = "i       love        shanghai    so  much"
 4 regex = r" +"                  # 切割空格,+表示一个到多个,有贪婪行为,把空格全切了
 5 lt = re.split(regex,str1)
 6 print(lt)                      # ["i", "love", "shanghai", "so", "much"]
 7 
 8 str2 = "i       love        shanghai    so  much"
 9 regex = r" +?"                 # 切割空格  +表示一个到多个, ?取消贪婪行为,能少切就少切
10 lt = re.split(regex,str2)
11 print(lt)                      # ["i", "", "", "", "", "", "", "love", "", "", "", "", "", "", "", "shanghai", "", "", "", "so", "", "much"]
12 
13 str3 = "dasfas23141sfa123dsafas13dasdfa1231241____3241234^&*&(dsafa
14 214331asdfa"
15 regex = r"d+?"
16 lt = re.split(regex,str3)
17 print(lt)    # ["dasfas", "", "", "", "", "sfa", "", "", "dsafas", "", "dasdfa", "", "", "", "", "", "", "____", "", "", "", "", "", "", "^&*&(dsafa", "", "", "", "", "", "asdfa"]
18 
19 regex1 = r"d+"
20 lt1 = re.split(regex1,str3)
21 print(lt1)   # ["dasfas", "sfa", "dsafas", "dasdfa", "____", "^&*&(dsafa", "asdfa"]

 

2. 正则表达式修饰符 - 可选标志(flags)

正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:

re.I:使匹配对大小写不敏感,忽略大小写

re.L:做本地化识别(locale-aware)匹配,表示特殊字符集 w, W, , B, s, S 依赖于当前环境

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

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

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

re.X:该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解,即为了增加可读性,忽略空格和 # 后面的注释

 

3. 正则中元字符的使用

正则表达式模式:模式字符串使用特殊的语法来表示一个正则表达式:字母和数字表示他们自身。一个正则表达式模式中的字母和数字匹配同样的字符串。多数字母和数字前加一个反斜杠时会拥有不同的含义。标点符号只有被转义时才匹配自身,否则它们表示特殊的含义。反斜杠本身需要使用反斜杠转义。由于正则表达式通常都包含反斜杠,所以你最好使用原始字符串来表示它们。模式元素(如 r" ",等价于 "\t")匹配相应的特殊字符。下表列出了正则表达式模式语法中的特殊元素。如果你使用模式的同时提供了可选的标志参数,某些模式元素的含义会改变。

匹配单个字符(数字、英文、其它...)符号位:

[ ]表示一字符位

[9876123450]表示一位,取值范围:[0,9]中间的任何一位值

[0-9]表示一位,取值范围:[0,9]中间的任何一位值

d表示一位,取值范围:[0,9]中间的任何一位值

D对以上的d进行取反,意味着:匹配除了数字字符以外的所有字符

[24680]表示一位,取值范围:24680中的任何一个值

[abcdefg]表示一位,取值范围:abcdefg中的任何一个值

[a-z]表示一位,取值范围:[a,z]中的任何一个值

[A-Z]表示一位,取值范围:[A,Z]中的任何一个值

[0-9a-zA-Z_]表示一位,取值范围:0~9a~zA~Z以及_中的任何一个值

w表示一位,取值范围:0~9a~zA~Z以及_中的任何一个值

Ww进行取反操作,意味着:匹配除了0~9a~zA~Z以及_中的其它所有字符

 

. 匹配除了换行符以外的所有字符

 

匹配锚字符(边界字符)

^从字符串数据的头部开始匹配,在开启了多行模式的情况下(re.M),它可以尝试匹配每一行的头部数据

$从字符串数据的尾部开始匹配,在开启了多行模式的情况下(re.M),它可以尝试匹配每一行的尾部数据 

A从字符串数据的头部开始匹配,在开启了多行模式的情况下(re.M),它没有多行的概念,还是匹配第一行的头部数据

 

从字符串数据的尾部开始匹配,在开启了多行模式的情况下(re.M),它没有多行的概念,还是匹配最后一行的尾部数据

补充:

尝试匹配边界(左侧、右侧)数据,如果一旦满足返回对象(matchlist)

 

B先舍弃规定边界的数据,然后一定满足从左侧开始匹配数据,...

 

匹配多个字符:

以下的一些x,y,n等都是变量名

 

1).模糊匹配:

x?:表示0个或者1     取值范围:[0,1]

x+:表示1个或者多个    取值范围:[1,无穷大)

 

x*:表示0个或者多个    取值范围:[0,无穷大)

2).精确匹配:

n{x}   n匹配x

 

n{x,}  n最少有x次,最多无穷大       范围:[x,无穷多)

n{x,y}n最少有x次,最多有y        范围:[x,y]

 

得到 None 

推荐阅读
  • 本指南从零开始介绍Scala编程语言的基础知识,重点讲解了Scala解释器REPL(读取-求值-打印-循环)的使用方法。REPL是Scala开发中的重要工具,能够帮助初学者快速理解和实践Scala的基本语法和特性。通过详细的示例和练习,读者将能够熟练掌握Scala的基础概念和编程技巧。 ... [详细]
  • 本文总结了JavaScript的核心知识点和实用技巧,涵盖了变量声明、DOM操作、事件处理等重要方面。例如,通过`event.srcElement`获取触发事件的元素,并使用`alert`显示其HTML结构;利用`innerText`和`innerHTML`属性分别设置和获取文本内容及HTML内容。此外,还介绍了如何在表单中动态生成和操作``元素,以便更好地处理用户输入。这些技巧对于提升前端开发效率和代码质量具有重要意义。 ... [详细]
  • 在Android应用开发中,实现与MySQL数据库的连接是一项重要的技术任务。本文详细介绍了Android连接MySQL数据库的操作流程和技术要点。首先,Android平台提供了SQLiteOpenHelper类作为数据库辅助工具,用于创建或打开数据库。开发者可以通过继承并扩展该类,实现对数据库的初始化和版本管理。此外,文章还探讨了使用第三方库如Retrofit或Volley进行网络请求,以及如何通过JSON格式交换数据,确保与MySQL服务器的高效通信。 ... [详细]
  • Objective-C 中的委托模式详解与应用 ... [详细]
  • 第六章:枚举类型与switch结构的应用分析
    第六章深入探讨了枚举类型与 `switch` 结构在编程中的应用。枚举类型(`enum`)是一种将一组相关常量组织在一起的数据类型,广泛存在于多种编程语言中。例如,在 Cocoa 框架中,处理文本对齐时常用 `NSTextAlignment` 枚举来表示不同的对齐方式。通过结合 `switch` 结构,可以更清晰、高效地实现基于枚举值的逻辑分支,提高代码的可读性和维护性。 ... [详细]
  • iOS 设备唯一标识获取的高效解决方案与实践
    在iOS 7中,苹果公司再次禁止了对MAC地址的访问,使得开发者无法直接获取设备的物理地址。为了在开发过程中实现设备的唯一标识,苹果推荐使用Keychain服务来存储和管理唯一的标识符。此外,还可以结合其他技术手段,如UUID和广告标识符(IDFA),以确保设备的唯一性和安全性。这些方法不仅能够满足应用的需求,还能保护用户的隐私。 ... [详细]
  • 本文探讨了 Java 中 Pair 类的历史与现状。虽然 Java 标准库中没有内置的 Pair 类,但社区和第三方库提供了多种实现方式,如 Apache Commons 的 Pair 类和 JavaFX 的 javafx.util.Pair 类。这些实现为需要处理成对数据的开发者提供了便利。此外,文章还讨论了为何标准库未包含 Pair 类的原因,以及在现代 Java 开发中使用 Pair 类的最佳实践。 ... [详细]
  • 在Java编程中,`String`对象既可以用作对象,也可以用作基本类型。本文深入解析了`String`对象中`equals`方法与`==`运算符的区别及其应用场景。`equals`方法用于比较两个字符串的内容是否相同,而`==`运算符则用于比较两个字符串对象的引用是否相同。通过具体示例和代码片段,文章详细阐述了这两种比较方式的内在机制和适用场景,帮助开发者更好地理解和使用`String`对象的比较操作。 ... [详细]
  • 本文探讨了利用Python实现高效语音识别技术的方法。通过使用先进的语音处理库和算法,本文详细介绍了如何构建一个准确且高效的语音识别系统。提供的代码示例和实验结果展示了该方法在实际应用中的优越性能。相关文件可从以下链接下载:链接:https://pan.baidu.com/s/1RWNVHuXMQleOrEi5vig_bQ,提取码:p57s。 ... [详细]
  • 本文探讨了 Kafka 集群的高效部署与优化策略。首先介绍了 Kafka 的下载与安装步骤,包括从官方网站获取最新版本的压缩包并进行解压。随后详细讨论了集群配置的最佳实践,涵盖节点选择、网络优化和性能调优等方面,旨在提升系统的稳定性和处理能力。此外,还提供了常见的故障排查方法和监控方案,帮助运维人员更好地管理和维护 Kafka 集群。 ... [详细]
  • 本文探讨了资源访问的学习路径与方法,旨在帮助学习者更高效地获取和利用各类资源。通过分析不同资源的特点和应用场景,提出了多种实用的学习策略和技术手段,为学习者提供了系统的指导和建议。 ... [详细]
  • 深入理解 Java 控制结构的全面指南 ... [详细]
  • 本文详细探讨了MySQL数据库实例化参数的优化方法及其在实例查询中的应用。通过具体的源代码示例,介绍了如何高效地配置和查询MySQL实例,为开发者提供了有价值的参考和实践指导。 ... [详细]
  • 在Android 4.4系统中,通过使用 `Intent` 对象并设置动作 `ACTION_GET_CONTENT` 或 `ACTION_OPEN_DOCUMENT`,可以从相册中选择图片并获取其路径。具体实现时,需要为 `Intent` 添加相应的类别,并处理返回的 Uri 以提取图片的文件路径。此方法适用于需要从用户相册中选择图片的应用场景,能够确保兼容性和用户体验。 ... [详细]
  • 在前文探讨了Spring如何为特定的bean选择合适的通知器后,本文将进一步深入分析Spring AOP框架中代理对象的生成机制。具体而言,我们将详细解析如何通过代理技术将通知器(Advisor)中包含的通知(Advice)应用到目标bean上,以实现切面编程的核心功能。 ... [详细]
author-avatar
渭南电信贺平
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有