Python 正则表达式

更新时间:2020-08-18 10:45:48 点击次数:1090次
什么是正则表达式
正则表达式(Regular Expression),常简写为 regex 或者 RE,又称为规则表达式。它不是某个编程语言所特有的,而是计算机科学的一个概念,通常被用来检索个替换符合某些规则的文本。目前,正则表达式已经在各种计算机语言(如 Java、C++ 和 Python 等)中得到了广泛的应用和发展。

正则表达式语法
行定位符:用来描述字符串的边界,‘^’ 表示行的开始,’$’ 表示行的结尾;

元字符:

代码 说明
. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意的空白符
\d 匹配数字
\b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
重复:
限定符 说明 举例
? 匹配前面的字符零次或一次 colou?r,该表达式可以匹配 colour 和 color
+ 匹配前面的字符一次或多次 go+gle,该表达式可以匹配的范围从 gogle 到 goo…gle
* 匹配前面的字符零次或多次 go*gle,该表达式可以匹配的范围从 ggle 到 goo…gle
{n} 匹配前面的字符 n 次 go{2}gle,该表达式只匹配
{n,} 匹配前面的字符最少 n 次 go{2,}gle,该表达式可以匹配的范围从 到 goo…gle
{n,m} 匹配前面的字符最少 n 次,最多 m 次 employe{0,2},该表达式可以匹配 employ、employe 和 employee
字符类:匹配数字和字符除了可以用 ‘\d’ 和 ‘\w’ 之外,像 [aeiou] 可以匹配任意一个英文元音字母,可以轻松制定一个字符范围。如果想匹配字符串中任意一个汉字,可以使用 [\u4e00-\u9fa5],如果要匹配连续多个汉字,可以使用 [\u4e00-\u9fa5]+;

排除字符:’^’ 字符如果放在方括号中,表示排除的意思。例如:[^a-zA-Z]该表达式用于匹配一个不是字母的字符;

选择字符:当包含着条件选择的逻辑时,就需要使用选择字符 ‘|’,该字符可以理解为 ‘或’。例如:(^\d{15}$) | (^\d{18}$) | (^\d{17})(\d|X|x)$该字符串的意思是可以匹配 15 位数字,或者 18 位数字,或者 17 位数字和最后一位(可以是数字、x 或者 X);

转义字符:正则表达式中的转义字符 ‘\’ 和 Python 字符串中的转义字符大同小异,都是将特殊字符变为普通字符;

分组:在正则表达式中,小括号的作用有两个,一个是改变限定符的作用范围,还有就是分组。例如:(\.[0-9]{1,3}){3}就是对小组中内容的重复操作;

使用 re 模块实现正则表达式操作
Python 中提供了 re 模块,用于实现正则表达式的操作。使用前先导入:import re

匹配字符串
使用 match() 方法进行匹配
match() 方法用于从字符串的开始处进行匹配,如果在起始位置匹配成功,则返回 Match 对象,否则返回 None,其语法格式如下:
re.match(pattern, string, [flags])
pattern:表示模式字符串,由要匹配的正则表达式转换而来;
string:表示要匹配的字符串;
flags:可选参数,表示标志位,用于控制匹配方向,如是否区分字母大小写。常用的标志如下表所示:
标志 说明
A 或 ASCII 对于 \w、\W、\b、\B、\d、\D、\s 和 \S 只进行 ASCII 匹配(仅适用于 Python 3.x)
I 或 IGNORECASE 执行不区分字母大小写的匹配
M 或 MULTILINE 将 ^ 和 $ 用于包括整个字符串的开始和结尾的每一行(默认情况下,仅适用于整个字符串的开始和结尾处)
S 或 DOTALL 使用 ‘.’ 字符匹配所有字符,包括换行符
X 或 VERBOSE 忽略模式字符串中未转义的空格和注释
示例1:

import re

pattern = r'mr_\w+'                        # 模式字符串
string = '项目名称:MR_SHOP mr_shop'          # 要匹配的字符串
match = re.match(pattern, string, re.I)      # 匹配字符串,不区分大小写
print(match)

string = 'MR_SHOP mr_shop'
match = re.match(pattern, string, re.I)
print(match)
print('匹配值得起始位置:', match.start())
print('匹配值得结束位置:', match.end())
print('匹配位置的元组:', match.span())
print('要匹配的字符串:', match.string)
print('匹配数据:', match.group())

上述例子的运行结果为:

None
<re.Match object; span=(0, 7), match='MR_SHOP'>
匹配值得起始位置: 0
匹配值得结束位置: 7
匹配位置的元组: (0, 7)
要匹配的字符串: MR_SHOP mr_shop
匹配数据: MR_SHOP

示例2:

import re

pattern = r'(13[4-9]\d{8})$|(15[01289]\d{8})$'
mobile = '13222222222'
match = re.match(pattern, mobile)
if match == None:
    print(mobile, "不是有效的中国移动手机号码。")
else:
    print(mobile, "是有效的中国移动手机号码。")

mobile = '15800000000'
if match == None:
    print(mobile, "不是有效的中国移动手机号码。")
else:
    print(mobile, "是有效的中国移动手机号码。")

上述例子的运行结果为:

13222222222 不是有效的中国移动手机号码。
15800000000 不是有效的中国移动手机号码。

使用 search() 方法进行匹配
search() 方法与 match() 方法的区别在于,match 是只在起始位置匹配,而 search 是在整个字符串中搜索,其语法格式和 match 一致,如下:
re.search(pattern, string, [flags])
示例1:

import re

pattern = r'mr_\w+'                          # 模式字符串
string = '项目名称:MR_SHOP mr_shop' # 要匹配的字符串
match = re.search(pattern, string, re.I) # 匹配字符串,不区分大小写
print(match)

string = 'MR_SHOP mr_shop'
match = re.search(pattern, string, re.I)
print(match)

上述例子的运行结果为:

<re.Match object; span=(5, 12), match='MR_SHOP'>
<re.Match object; span=(0, 7), match='MR_SHOP'>

示例2:

import re

pattern = r'(黑客)|(抓包)|(监听)|(Trojan)'
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下 Trojan'
match = re.search(pattern, about)
if match == None:
    print(about, '@ 安全!')
else:
    print(about, '@ 出现了危险词汇!')

about = '我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站'
match = re.search(pattern, about)
if match == None:
    print(about, '@ 安全!')
else:
    print(about, '@ 出现了危险词汇!')

上述例子的运行结果为:

我是一名程序员,我喜欢看黑客方面的图书,想研究一下 Trojan @ 出现了危险词汇!
我是一名程序员,我喜欢看计算机网络方面的图书,喜欢开发网站 @ 安全!

使用 findall() 方法进行匹配
findall() 方法用于在整个字符串中搜索所有符合正则表达式的字符串,并以列表的形式返回。如果匹配失败,则返回空列表,其语法格式和 match、search 一致,如下:
re.findall(pattern, string, [flags])
示例1:

import re

pattern = r'mr_\w+'                         # 模式字符串
string = '项目名称:MR_SHOP mr_shop'         # 要匹配的字符串
match = re.findall(pattern, string, re.I)   # 匹配字符串,不区分大小写
print(match)

string = 'MR_SHOP mr_shop'
match = re.findall(pattern, string)         # 匹配字符串,区分大小写
print(match)

上述例子的运行结果为:

['MR_SHOP', 'mr_shop']
['mr_shop']

示例2:

import re

pattern1 = r'[1-9]{1,3}(\.[0-9]{1,3}){3}'
str = '127.0.0.1 192.168.1.66'
match = re.findall(pattern1, str)
print(match)

pattern1 = r'([1-9]{1,3}(\.[0-9]{1,3}){3})'
match = re.findall(pattern1, str)
print(match)

for item in match:
    print(item[0])

上述例子的运行结果为:

['.1', '.66']
[('127.0.0.1', '.1'), ('192.168.1.66', '.66')]
127.0.0.1
192.168.1.66

注意:如果模式字符串中出现分组,那么得到的结果是根据分组进行匹配的结果。如果想获取整个模式字符串的匹配,可以将整个模式字符串使用一对小括号进行分组。然后在获取结果时,只取返回值列表的每个元素的第一个元素。

替换字符串
sub() 方法用于时显示字符串替换。其语法格式如下:
re.sub(pattern, repl, string, count, flags)
pattern:表示模式字符串,由要匹配的正则表达式转换而来;
repl:表示替换的字符串;
string:表示要被查找替换的原始字符串;
count:可选参数,表示模式匹配后替换的最大次数;
flags:可选参数,表示标志位,用于控制匹配方式,如是否区分字母大小写;
示例:

import re

pattern = r'1[34578]\d{9}'
string = '中奖号码为:84978981 联系电话为:13611111111'
result = re.sub(pattern, '1XXXXXXXXXX', string)      # 隐藏字符串中的手机号
print(result)

pattern = r'(黑客)|(抓包)|(监听)|(Trojan)'
about = '我是一名程序员,我喜欢看黑客方面的图书,想研究一下 Trojan'
sub = re.sub(pattern, '@__@', about) # 替换出现的危险字符
print(sub)

上述例子的运行结果为:

中奖号码为:84978981 联系电话为:1XXXXXXXXXX
我是一名程序员,我喜欢看@__@方面的图书,想研究一下 @__@

使用正则表达式分割字符串
split() 方法用于实现根据正则表达式分割字符串,并以列表的形式返回。其作用与字符串对象的 split() 方法类似,所不同的就是分割字符由模式字符串指定,其语法格式如下:
re.split(pattern, string, [maxsplit], [flags])
示例:

import re

str = '@马云 @马化腾 @刘强东'
pattern = r'\s*@'
list = re.split(pattern, str)
print('我的好友有:')
for item in list:
    if item != "":
        print(item)

上述例子的运行结果为:

我的好友有:
马云
马化腾
刘强东

本站文章版权归原作者及原出处所有 。内容为作者个人观点, 并不代表本站赞同其观点和对其真实性负责,本站只提供参考并不构成任何投资及应用建议。本站是一个个人学习交流的平台,网站上部分文章为转载,并不用于任何商业目的,我们已经尽可能的对作者和来源进行了通告,但是能力有限或疏忽,造成漏登,请及时联系我们,我们将根据著作权人的要求,立即更正或者删除有关内容。本站拥有对此声明的最终解释权。

回到顶部
嘿,我来帮您!