Python 正则表达式

作者:billy
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

什么是正则表达式

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

正则表达式语法

  1. 行定位符:用来描述字符串的边界,‘^’ 表示行的开始,’$’ 表示行的结尾;

  2. 元字符:

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

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

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

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

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

使用 re 模块实现正则表达式操作

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

  1. 匹配字符串
  • 使用 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

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

  1. 替换字符串
    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
我是一名程序员,我喜欢看@__@方面的图书,想研究一下 @__@
  1. 使用正则表达式分割字符串
    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)

上述例子的运行结果为:

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

更多请参考

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值