一文搞定Python正则表达式

纵然是瞬间 提交于 2020-08-10 04:46:12

本文对正则表达式和 Python 中的 re 模块进行详细讲解

很多人学习python,不知道从何学起。
很多人学习python,掌握了基本语法过后,不知道在哪里寻找案例上手。
很多已经做案例的人,却不知道如何去学习更加高深的知识。
那么针对这三类人,我给大家提供一个好的学习平台,免费领取视频教程,电子书籍,以及课程的源代码!
QQ群:1097524789



  • 什么是正则表达式

  • 正则表达式作用

  • 元字符及含义

  • re模块详解

  • 正则表达式修饰符

  • 正则表达式实例

本文目录

什么是正则表达式

正则表达式(regular expression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

正则表达式作用

通过使用正则表达式,可以:

  1. 测试字符串内的模式 例如,可以测试输入字符串,以查看字符串内是否出现电话号码模式或信用卡号码模式。这称为数据验证。

  2. 替换文本 可以使用正则表达式来识别文档中的特定文本,完全删除该文本或者用其他文本替换它。

  3. 基于模式匹配从字符串中提取子字符串 可以查找文档内或输入域内特定的文本,例如通过爬虫从网页内容中直接需要的内容

元字符及含义

常用元字符

符号 含义
点. 匹配除换行符外的任意字符
星号* 匹配0个或者多个任意字符
问号? 匹配0个或者1个任意字符(非贪婪模式)
^ 开始位置
$ 结束位置
\s 匹配任意空白
\S 匹配任意非空白
\d 匹配一个数字
\D 匹配一个非数字
\w 匹配一个单词字符,包含数字和字母
\W 匹配一个非单词字符,包含数字和字母
[abcd] 匹配abcd中的一个任意字符
[^abcd] 匹配不含包abcd的任意字符
+ 匹配1次或者多次前面的内容
{n} 匹配n词(固定)
{n,} 匹配至少n次
{n,m} 匹配n到m次
x|y 匹配x或者y
() 匹配括号内的内容

元字符

下面是比较完整的元字符匹配表格

元字符 描述
\ 将下一个字符标记符、或一个向后引用、或一个八进制转义符。例如,“\n”匹配\n。“\n”匹配换行符。序列“\”匹配“\”而“(”则匹配“(”。即相当于多种编程语言中都有的“转义字符”的概念。
^ 匹配输入字行首。如果设置了RegExp对象的Multiline属性,^也匹配“\n”或“\r”之后的位置。
$ 匹配输入行尾。如果设置了RegExp对象的Multiline属性,$也匹配“\n”或“\r”之前的位置。
* 匹配前面的子表达式任意次。例如,zo*能匹配“z”,也能匹配“zo”以及“zoo”。*等价于{0,}。
+ 匹配前面的子表达式一次或多次(大于等于1次)。例如,“zo+”能匹配“zo”以及“zoo”,但不能匹配“z”。+等价于{1,}。
? 匹配前面的子表达式零次或一次。例如,“do(es)?”可以匹配“do”或“does”。?等价于{0,1}。
n } n 是一个非负整数。匹配确定的 n 次。例如,“o{2}”不能匹配“Bob”中的“o”,但是能匹配“food”中的两个o。
n ,} n 是一个非负整数。至少匹配 n 次。例如,“o{2,}”不能匹配“Bob”中的“o”,但能匹配“foooood”中的所有o。“o{1,}”等价于“o+”。“o{0,}”则等价于“o*”。
n , m } m 和 n 均为非负整数,其中 n <= m 。最少匹配 n 次且最多匹配 m 次。例如,“o{1,3}”将匹配“fooooood”中的前三个o为一组,后三个o为一组。“o{0,1}”等价于“o?”。请注意在逗号和两个数之间不能有空格。
? 当该字符紧跟在任何一个其他限制符(*,+,?,{ n },{ n ,},{ n , m })后面时,匹配模式是非贪婪的。非贪婪模式尽可能少地匹配所搜索的字符串,而默认的贪婪模式则尽可能多地匹配所搜索的字符串。例如,对于字符串“oooo”,“o+”将尽可能多地匹配“o”,得到结果[“oooo”],而“o+?”将尽可能少地匹配“o”,得到结果 ['o', 'o', 'o', 'o']
.点 匹配除“\n”和"\r"之外的任何单个字符。要匹配包括“\n”和"\r"在内的任何字符,请使用像“[\s\S]”的模式。( 不匹配换行符 )
(pattern) 匹配pattern并获取这一匹配。所获取的匹配可以从产生的Matches集合得到,在VBScript中使用SubMatches集合,在JScript中则使用 9属性。要匹配圆括号字符,请使用“(”或“)”。
(?:pattern) 非获取匹配,匹配pattern但不获取匹配结果,不进行存储供以后使用。这在使用或字符“(|)”来组合一个模式的各个部分时很有用。例如“industr(?:y|ies)”就是一个比“industry|industries”更简略的表达式。
(?=pattern) 非获取匹配,正向肯定预查,在任何匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如,“Windows(?=95|98|NT|2000)”能匹配“Windows2000”中的“Windows”,但不能匹配“Windows3.1”中的“Windows”。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
(?!pattern) 非获取匹配,正向否定预查,在任何不匹配pattern的字符串开始处匹配查找字符串,该匹配不需要获取供以后使用。例如“Windows(?!95|98|NT|2000)”能匹配“Windows3.1”中的“Windows”,但不能匹配“Windows2000”中的“Windows”。
(?<=pattern) 非获取匹配,反向肯定预查,与正向肯定预查类似,只是方向相反。例如,“(?<=95|98|NT|2000)Windows”能匹配“2000Windows”中的“Windows”,但不能匹配“3.1Windows”中的“Windows”。*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等
(?<!patte_n) 非获取匹配,反向否定预查,与正向否定预查类似,只是方向相反。例如“(?<!95|98|NT|2000)Windows”能匹配“3.1Windows”中的“Windows”,但不能匹配“2000Windows”中的“Windows”。*python的正则表达式没有完全按照正则表达式规范实现,所以一些高级特性建议使用其他语言如java、scala等
x|y 匹配x或y。例如,“z|food”能匹配“z”或“food”(此处请谨慎)。“[z|f]ood”则匹配“zood”或“food”。
[xyz] 字符集合。匹配所包含的任意一个字符。例如,“[abc]”可以匹配“plain”中的“a”。
[^xyz] 负值字符集合。匹配未包含的任意字符。例如,“[^abc]”可以匹配“plain”中的“plin”任一字符。
[a-z] 字符范围。匹配指定范围内的任意字符。例如,“[a-z]”可以匹配“a”到“z”范围内的任意小写字母字符。注意:只有连字符在字符组内部时,并且出现在两个字符之间时,才能表示字符的范围; 如果出字符组的开头,则只能表示连字符本身.
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,“[^a-z]”可以匹配任何不在“a”到“z”范围内的任意字符。
\b 匹配一个单词的边界,也就是指单词和空格间的位置(即正则表达式的“匹配”有两种概念,一种是匹配字符,一种是匹配位置,这里的\b就是匹配位置的)。例如,“er\b”可以匹配“never”中的“er”,但不能匹配“verb”中的“er”;“\b1_”可以匹配“1_23”中的“1_”,但不能匹配“21_3”中的“1_”。
\B 匹配非单词边界。“er\B”能匹配“verb”中的“er”,但不能匹配“never”中的“er”。
\cx 匹配由x指明的控制字符。例如,\cM匹配一个Control-M或回车符。x的值必须为A-Z或a-z之一。否则,将c视为一个原义的“c”字符。
\d 匹配一个数字字符。等价于[0-9]。grep 要加上-P,perl正则支持
\D 匹配一个非数字字符。等价于[^0-9]。grep要加上-P,perl正则支持
\f 匹配一个换页符。等价于\x0c和\cL。
\n 匹配一个换行符。等价于\x0a和\cJ。
\r 匹配一个回车符。等价于\x0d和\cM。
\s 匹配任何不可见字符,包括空格、制表符、换页符等等。等价于[ \f\n\r\t\v]。
\S 匹配任何可见字符。等价于[^ \f\n\r\t\v]。
\t 匹配一个制表符。等价于\x09和\cI。
\v 匹配一个垂直制表符。等价于\x0b和\cK。
\w 匹配包括下划线的任何单词字符。类似但不等价于“[A-Za-z0-9_]”,这里的"单词"字符使用Unicode字符集。
\W 匹配任何非单词字符。等价于“[^A-Za-z0-9_]”。
\x n 匹配 n ,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如,“\x41”匹配“A”。“\x041”则等价于“\x04&1”。正则表达式中可以使用ASCII编码。
*num* 匹配 num ,其中 num 是一个正整数。对所获取的匹配的引用。例如,“(.)\1”匹配两个连续的相同字符。
*n* 标识一个八进制转义值或一个向后引用。如果*n 之前至少 n 个获取的子表达式,则 n 为向后引用。否则,如果 n 为八进制数字(0-7),则 n*为一个八进制转义值。
*nm* 标识一个八进制转义值或一个向后引用。如果*nm 之前至少有 nm 个获得子表达式,则 nm 为向后引用。如果*nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的向后引用。如果前面的条件都不满足,若 n 和 m 均为八进制数字(0-7),则*nm 将匹配八进制转义值 nm*。
*nml* 如果 n 为八进制数字(0-7),且 m 和 l 均为八进制数字(0-7),则匹配八进制转义值 nml 。
\u n 匹配 n ,其中 n 是一个用四个十六进制数字表示的Unicode字符。例如,\u00A9匹配版权符号(©)。
\p{P} 小写 p 是 property 的意思,表示 Unicode 属性,用于 Unicode 正表达式的前缀。中括号内的“P”表示Unicode 字符集七个字符属性之一:标点字符。其他六个属性:L:字母;M:标记符号(一般不会单独出现);Z:分隔符(比如空格、换行等);S:符号(比如数学符号、货币符号等);N:数字(比如阿拉伯数字、罗马数字等);C:其他字符。* 注:此语法部分语言不支持,例:javascript。
<> 匹配词(word)的开始(<)和结束(>)。例如正则表达式<the>能够匹配字符串"for the wise"中的"the",但是不能匹配字符串"otherwise"中的"the"。注意:这个元字符不是所有的软件都支持的。
( ) 将( 和 ) 之间的表达式定义为“组”(group),并且将匹配这个表达式的字符保存到一个临时区域(一个正则表达式中最多可以保存9个),它们可以用 \1 到\9 的符号来引用。
| 将两个匹配条件进行逻辑“或”(or)运算。例如正则表达式(him|her) 匹配"it belongs to him"和"it belongs to her",但是不能匹配"it belongs to them."。注意:这个元字符不是所有的软件都支持的。

re模块详解

python 中提供了 re 模块来处理正则表达式问题,下面讲解几个常用的方法

re.match

re.match 尝试从字符串的 起始位置 匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。

该方法返回的是一个正则匹配对象

语法

import re
re.match(pattern, string, flags=0)
复制代码

参数说明

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。

demo

  • 通过  group() 来获取内容
  • 通过  span() 来获取范围
# 最常规的匹配
content = "Hello 1234567 World_This is a Regex Demo"
print(len(content))
result = re.match("^Hello\s\d+\s\w{10}.*?Demo$", content) # 一定是从起始位置开始匹配的 # result = re.match("^Hello\s\d{7}\s\w{10}.*?Demo$", content) print(result) print(result.group()) print(result.span()) 复制代码

如果存在换行符,使用标志位 re.S

# 如果存在换行,使用标志位符号

content = """Hello 1234567 World_This is a Regex Demo.
My name is Peter
I am from shenzhen
""" print(len(content)) result = re.match("^Hello\s\d+\s.*?shenzhen$", content, re.S) # result = re.match("^Hello\s\d{7}\s\w{10}.*?Peter$", content) print(result) print(result.group()) print(result.span()) 复制代码

line = "Cats are smarter than dogs"

matchObj = re.match( r'(.*) are (.*?) .*?', line, re.M|re.I)

if matchObj:
    print ("matchObj.group() : ", matchObj.group()) # 返回的是全部内容 print ("matchObj.group(1) : ", matchObj.group(1)) # 返回第1个()中的内容 print ("matchObj.group(2) : ", matchObj.group(2)) # 第2个 else: print ("No match!!") 复制代码

re.match 尽量少用

re.match 尽量少用

re.match 尽量少用

re.search

re.search 扫描整个字符串并返回 第一个成功 的匹配,否则返回None。该方法不要求从起始位置开始。一旦找到第一个符合要求的内容,就会停止查找

可以使用 group(num) 或 groups() 匹配对象函数来获取匹配表达式的结果。

函数语法

re.search(pattern, string, flags=0)
复制代码

参数说明

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等

demo

  1. 返回匹配成功的第一个元素

  2. group()方法中的参数不能超过括号的个数

re.findall

re.findall 是扫描整个字符串,通过 列表的形式返回所有的符合条件的元素

语法

findall(pattern, string, flags=0)
复制代码

参数说明

参数 描述
pattern 匹配的正则表达式
string 要匹配的字符串。
flags 标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等

demo

结果是列表形式

如果提取的内容中包含多个 .*? ,那么返回的仍然是列表形式,只是里面的元素变成了元组的形式

re.sub

通过正则表达式来替换字符串中的某些内容

语法

re.sub(pattern, repl, string, count)  
复制代码

参数说明

参数的含义分别为:

  • 正则表达式

  • 替换的内容

  • 原始字符串

  • 替换的个数,默认是0,全部替换

demo

sub特殊处理

re.sub 允许使用函数对匹配项进行特殊的处理

两种模式

两种模式指的是:贪婪模式和非贪婪模式

3个符号

我们在正则表达式中经常会使用3个符号:

  • 点.:表示匹配的是除去换行符之外的任意字符

  • 问号?:表示匹配0个或者1个

  • 星号*:表示匹配0个或者任意个字符

demo

解释

  1. aaaacb
    ab
    adceb
    
  2. 在贪婪模式的例子中,程序会找到 最长的那个符合要求的字符串

  3. 在最后的例子中,使用了  .? ,表示ab之间只能存在0个或者1个元素,所以结果中只有两种情况

正则表达式修饰符 - 可选标志

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

修饰符 描述
re.I 使匹配对大小写不敏感
re.L 做本地化识别(locale-aware)匹配
re.M 多行匹配,影响 ^ 和 $
re.S 使 . 匹配包括换行在内的所有字符
re.U 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B.
re.X 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解。

正则表达式实例

字符匹配

实例 描述
python 匹配 "python".

字符类

实例 描述
[Pp]ython 匹配 "Python" 或 "python" [Pp]中选择一个字母匹配
rub[ye] 匹配 "ruby" 或 "rube" [ye]中选择一个匹配
[aeiou] 匹配中括号内的任意一个字母 [aeiou]中匹配一个字母
[0-9] 匹配任何数字。类似于 [0123456789] 匹配任意多个数字
[a-z] 匹配任何小写字母
[A-Z] 匹配任何大写字母
[a-zA-Z0-9] 匹配任何字母及数字
[^aeiou] 除了aeiou字母以外的所有字符 ^表示取反操作
[^0-9] 匹配除了数字外的字符

特殊字符类

实例 描述
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。
\d 匹配一个数字字符。等价于 [0-9]。
\D 匹配一个 非数字字符 。等价于 [^0-9]。
\s 匹配任何空白字符 ,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。

总结

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!