Python 正则表达式学习总结
1 正则表达式基础知识点
1.1 正则表达式的概念
正则表达式:通常被用来检索、替换那些符合某个模式(规则)的文本,Python里默认是贪婪匹配。
常见的正则匹配规则
模式 | 描述 |
---|---|
^ | 匹配字符串的开头 |
$ | 匹配字符串的末尾 |
. | 匹配任意字符,除换行符外 |
* | 匹配 |
+ | 匹配 |
[…] | 表示一组字符,单独列出,例如:[amk]匹配’a’,‘m’或’‘k’ |
[^…] | 匹配不在[ ]中的字符,例如:[^abc]匹配除了a,b,c之外的字符 |
re* | 匹配0个或多个正则表达式 |
re+ | 匹配1个或多个正则表达式 |
re? | 匹配0个或1个由前面正则表达式定义的片段,非贪婪方式 |
re{n} | 精确匹配n个前面正则表达式 |
re{n,m} | 匹配n到m次由前面正则表达式定义的片段,贪婪匹配 |
( …) | 匹配括号内的表达式,也表示一个组 |
(?imx) | 正则表达式包含三种可选标志:i, m, 或 x 。只影响括号中的区域 |
(?-imx) | 正则表达式关闭 i, m, 或 x 可选标志。只影响括号中的区域 |
(?: re) | 类似 (…), 但是不表示一个组 |
(?imx: re) | 在括号中使用i, m, 或 x 可选标志 |
(?-imx: re) | 在括号中不使用i, m, 或 x 可选标志 |
(?#…) | 注释 |
\w | 匹配字母、数字及下划线 |
\W | 匹配非字母、数字及下划线 |
\s | 匹配任意空白字符,等价于[\t\n\r\f] |
\S | 匹配任意非空字符 |
\d | 匹配任意数字,等价于[0-9] |
\D | 匹配任意非数字 |
\A | 匹配字符串开始 |
\Z | 匹配字符串结束,如果是存在换行,只匹配到换行前的结束字符串 |
\z | 匹配字符串结束 |
\G | 匹配最后匹配完成的位置 |
\b | 匹配一个单词边界,也就是指单词和空格间的位置。例如:‘er\b’ 可以匹配"never" 中的 ‘er’,但不能匹配 “verb” 中的 ‘er’ |
\B | 匹配非单词边界。‘er\B’ 能匹配 “verb” 中的 ‘er’,但不能匹配 “never” 中的 ‘er’ |
\n, \t | 匹配一个换行符或制表符 |
\1…\9 | 匹配第n个分组的内容 |
[\u4e00-\u9fa5] | 匹配中文 |
1.2 正则表达式的常用方法
方法 | 作用 | 函数语法 |
---|---|---|
re.match | 尝试从字符串的起始位置匹配一个模式,不成功返回none | re.match(pattern, string, flags=0) |
re.search | 扫描整个字符串并返回第一个成功的匹配 | re.search(pattern, string, flags=0) |
re.sub | 替换字符串 | re.sub(pattern,replace,string) |
re.findall | 查找全部 | re.findall(pattern,string,flags=0) |
1.3 正则表达式修饰符-可选符号
正则表达式可以包含一些可选标志修饰符来控制匹配的模式。修饰符被指定为一个可选的标志。多个标志可以通过按位 OR(|) 它们来指定。如 re.I | re.M 被设置成 I 和 M 标志:
修饰符 | 作用 |
---|---|
re.I | 使匹配对大小写不敏感 |
re.L | 做本地化识别(locale-aware)匹配 |
re.S | 使 . 匹配包括换行在内的所有字符 |
re.U | 根据Unicode字符集解析字符。这个标志影响 \w, \W, \b, \B |
re.X | 该标志通过给予你更灵活的格式以便你将正则表达式写得更易于理解 |
2 正则表达式常用函数:
2.1 compile 函数详解
compile 函数:根据一个模式字符串和可选的标志参数生成一个正则表达式对象。该对象拥有一系列方法用于正则表达式匹配和替换。
re.match函数:
作用:re.match 尝试从字符串的起始位置匹配一个模式,如果不是起始位置匹配成功的话,match()就返回none。
语法:re.match(pattern, string, flags=0)
参数:pattern(匹配的正则表达式),string(要匹配的字符串),flags(标志位,用于控制正则表达式的匹配方式,如:是否区分大小写,多行匹配等等。参见:正则表达式修饰符 - 可选标志)
返回值:匹配成功re.match方法返回一个匹配的对象,否则返回None。
*注:match和search一旦匹配成功,就是一个match object对象,而match object对象有以下方法:
• start() 返回匹配开始的位置
• end() 返回匹配结束的位置
• span() 返回一个元组包含匹配 (开始,结束) 的位置
• group(num) 匹配的整个表达式的字符串,group() 可以一次输入多个组号,在这种情况下它将返回一个包含那些组所对应值的元组。
• groups() 返回一个包含所有小组字符串的元组,从 1 到 所含的小组号。
1.给定的字符串是否符合正则表达式的过滤逻辑(称作“匹配”);
2.可以通过正则表达式,从字符串中获取我们想要的特定部分。
1、字符串前加 u:
例:u"我是含有中文字符组成的字符串。"
作用:后面字符串以 Unicode 格式 进行编码,一般用在中文字符串前面,防止因为源码储存格式问题,导致再次使用时出现乱码。
2、字符串前加 r:
例:r"\n\n\n\n” # 表示一个普通生字符串 \n\n\n\n,而不表示换行了。
作用:去掉反斜杠的转移机制。
(特殊字符:即那些,反斜杠加上对应字母,表示对应的特殊含义的,比如最常见的”\n”表示换行,”\t”表示Tab等。 )
应用:
常用于正则表达式,对应着re模块。
3、字符串前加 b:
例: response = b’
Hello World!
’ # b’ ’ 表示这是一个 bytes 对象作用:b" "前缀表示:后面字符串是bytes 类型。
用处:
网络编程中,服务器和浏览器只认bytes 类型数据。
如:send 函数的参数和 recv 函数的返回值都是 bytes 类型
Python re正则匹配中文,其实非常简单,把中文的unicode字符串转换成utf-8格式就可以了,然后可以在re中随意调用
unicode中中文的编码为/u4e00-/u9fa5,因此正则表达式u”[\u4e00-\u9fa5]+”可以表示一个或者多个中文字符
3 正则表达式常见用法
3.1 单个位置的字符串提取
单个位置的字符串,使用findall配合正则表达式(.+?)来提取,结果返回一个匹配成功的list,该情形下为非贪婪匹配(用?来控制正则贪婪和非贪婪匹配)。
(1)非贪婪匹配:使用?控制只匹配0或1个最近的匹配结果;
str="a123b456b"
print(re.findall(r"a(.+?)b",str))
>>>
['123']
(2)贪婪匹配:尽可能多的匹配满足条件的结果;
str="a123b456b"
print(re.findall(r"a(.+)b",str))
#或者
print(re.findall(r"a(.*)b",str))
>>>
['123b456']
3.2 多行匹配
- 正常情况下,不能处理str过程中有\n(换行)的情况,即:仅为单行数据匹配;
- 若要实现多行匹配,需要加上
re.S
或re.M
标志,即:可以匹配换行符; - 默认正则表达式中使用^ 或 $ 只会匹配第一行,但是,加上
re.M
后,正则表达式中使用^或$或二者兼用都将会匹配每一行。
#单行数据匹配
str="a23b\na34b"
print(re.findall(r"a(\d+)b.+a(\d+)b",str))
>>>
[] #因为不能处理str中间有\n换行的情况
#解决方案:引入re.S来匹配\n换行符
print(re.findall(r"(\d+)b.+a(\d+)b",str,re.S))
>>>
[('23', '34')]
#多行匹配,引入re.M
str="a23b\na34b"
print(re.findall(r"^a(\d+)b",str))
>>>
['23']
print(re.findall(r"a(\d+)b$",str))
>>>
['34']
print(re.findall(r"^a(\d+)b$",str))
>>>
[]
print(re.findall(r"^a(\d+)b$",str,re.M))
#或者
print(re.findall(r"^a(\d+)b",str,re.M))
#或者
print(re.findall(r"a(\d+)b$",str,re.M))
>>>
['23', '34']
3.3 连续多个位置的字符串提取
3.4 常用正则表达式汇总
'abc’表示字符串中有’abc’就匹配成功
'[abc]'表示字符串中有’a’或’b’或’c’就匹配成功
'^abc’表示字符串由’abc’开头就匹配成功
'1'表示字符串由’a’或’b’或’c’开头的,
'[^abc]‘表示匹配’a’,‘b’,‘c’之外的字符。如果一个字符串是由’a’,‘b’,'c’组合起来的,那就是假
非负整数:^\d+$
正整数:^ [0-9] * [1-9][0-9]*$
非正整数:^((-\d+)|(0+))$
负整数:^-[0-9][1-9][0-9]$
整数:^-?\d+$
非负浮点数:^\d+(.\d+)?$
正浮点数 : ^((0-9)+.[0-9][1-9][0-9])|([0-9][1-9][0-9].[0-9]+)|([0-9][1-9][0-9])$
非正浮点数:^((-\d+.\d+)?)|(0+(.0+)?))$
负浮点数:^(-((正浮点数正则式)))$
英文字符串:^ [A-Za-z]+$
英文大写串:^ [A-Z]+$
英文小写串:^ [a-z]+$
英文字符数字串:^ [A-Za-z0-9]+$
英数字加下划线串:^\w+$
E-mail地址:^ [\w-]+(.[\w-]+)*@[\w-]+(.[\w-]+)+$
URL:^ [a-zA-Z]+://(\w+(-\w+))(.(\w+(-\w+)))(?\s)?$
或:^http://[A-Za-z0-9]+.[A-Za-z0-9]+[/=?%-&_~`@[]’:+!]( [ ^ <>""])$
邮政编码:^ [1-9]\d{5}$
中文:^ [\u0391-\uFFE5]+$
电话号码:^(((\d{2,3}))|(\d{3}-))?((0\d{2,3})|0\d{2,3}-)?[1-9]\d{6,7}(-\d{1,4})?$
手机号码:^(((\d{2,3}))|(\d{3}-))?13\d{9}$
双字节字符(包括汉字在内):^\x00-\xff
匹配首尾空格:(^\s*)|(\s*$)(像vbscript那样的trim函数)
匹配HTML标记:<(.)>.</\1>|<(.*) />
匹配空行:\n[\s| ]*\r
提取信息中的网络链接:(h|H)(r|R)(e|E)(f|F) *= *(’|")?(\w|\|/|.)+(’|"| *|>)?
提取信息中的邮件地址:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
提取信息中的图片链接:(s|S)(r|R)(c|C) *= *(’|")?(\w|\|/|.)+(’|"| *|>)?
提取信息中的IP地址:(\d+).(\d+).(\d+).(\d+)
提取信息中的中国手机号码:(86)013\d{9}
提取信息中的中国固定电话号码:((\d{3,4})|\d{3,4}-|\s)?\d{8}
提取信息中的中国电话号码(包括移动和固定电话):((\d{3,4})|\d{3,4}-|\s)?\d{7,14}
提取信息中的中国邮政编码:[1-9]{1}(\d+){5}
提取信息中的浮点数(即小数):(-?\d*).?\d+
提取信息中的任何数字 :(-?\d*)(.\d+)?
IP:(\d+).(\d+).(\d+).(\d+)
电话区号:/^0\d{2,3}$/
腾讯QQ号:^ [1-9][1-9][0-9]$
帐号(字母开头,允许5-16字节,允许字母数字下划线):2[a-zA-Z0-9_]{4,15}$
中文、英文、数字及下划线:^ [\u4e00-\u9fa5_a-zA-Z0-9]+$
匹配中文字符的正则表达式: [\u4e00-\u9fa5]
匹配双字节字符(包括汉字在内):[ ^ \x00-\xff]
匹配空行的正则表达式:\n[\s| ]*\r
匹配HTML标记的正则表达式:/<(.)>.</\1>|<(.*) />/
sql语句:^(select|drop|delete|create|update|insert).*$
匹配首尾空格的正则表达式:(^\s*)|(\s*$)
匹配Email地址的正则表达式:\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*
3.5 re库中group(), groups(), groupdict() 的用法区别
4 常见范例
(1)过滤掉除了中文以外的字符
str='hello,world!!%[545]你好,234世界。。。'
str=re.sub("[A-Za-z0-9\!\%\[\]\,\。]","",str)
print(str)
>>>
你好世界
pattern="[\u4e00-\u9fa5]+"
regex=re.compile(pattern)
results=regex.findall('adf中文adf发京东方')
print(results)
>>>
['中文', '发京东方']
(2)过滤掉除了中文以外的字符