Python_正则表达式:Day16

本文深入解析正则表达式的强大功能,从基础语法到高级应用,如分组、贪婪匹配及正则表达式的预编译技巧。通过实例演示如何进行字符串匹配、切分和提取,适用于各种编程需求。

前言

养成一个好的习惯只需要坚持21天,Day16

正则表达式

正则表达式是一种用来匹配字符串的强有力的武器,它用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
\d可以匹配一个数字,\w可以匹配一个字母或数字,比如下面的例子:

  • ‘00\d’ 可以匹配'007',但无法匹配'00A'
  • '\d\d\d'可以匹配'010';
  • '\w\w\d'可以匹配'py3'
  • 'py.'可以匹配'pyc'、'pyo'、'py!'等等。

.可以匹配任意字符。
要匹配变长的字符,在正则表达式中,用*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符。
举一个例子:\d{3}\s+\d{3,8}
其中\d{3}表示匹配3个数字,\s可以匹配一个空格,\s+表示至少有一个空格;\d{3,8}表示可以匹配3-8个数字。
匹配一个座机号码\d{3}\-\d{3,8},比如'010-12345',中间的-是特殊字符,在编写的时候需要用\转义。

进阶

要做更精确的匹配,可以使用[]表示范围,比如:

  • [0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
  • [0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如’a100’,‘0_Z’,'Py3000’等等;
  • [a-zA-Z\_][0-9a-zA-Z\_]*可以匹配由字母或下划线开头,后接任意个由一个数字、字母或者下划线组成的字符串,也就是Python合法的变量;
  • [a-zA-Z\_][0-9a-zA-Z\_]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。

A|B可以匹配A或B,所以(P|p)ython可以匹配’Python’或者’python’。
^表示行的开头,^\d表示必须以数字开头。
$表示行的结束,\d$表示必须以数字结束。

re模块

由之前的学习可知,可以使用\转义,也可以使用Python的r前缀,使用r前缀可以避免许多转义的问题。

s = r'ABC\-001' # Python的字符串
# 对应的正则表达式字符串不变:
# 'ABC\-001'

re模块中,使用match()方法判断是否匹配,匹配成功则返回一个Match对象,否则返回None。如下:

import re
test = '用户输入的测试字符串'
if re.match(r'正则表达式', test):  #re.match(r'^\d{3}\-\d{3,8}$', '010-12345')
	print('ok')
else:
	print('failed')
切分字符串

比如我们一般使用python的split()函数进行切分:

'a b  c'.split(' ')
#['a', 'b', '', 'c']无法识别字符串中连续的空格

使用正则表达式进行切分:

re.split(r'\s+','a b  c')
# ['a', 'b', 'c']

如果把划分规则变成逗号:

re.split(r'[\s\,]+','a,b,  c    d')
# ['a', 'b', 'c', 'd']

再加入分号,进行切分:

re.split(r'[\s\,\;]+','a,b;;  c    d')
# ['a', 'b', 'c', 'd']
分组

正则表达式除了能够进行字符串的匹配之外,还能提取子串。即对字符串的内容进行分组操作,用()表示。
^(\d{3})-(\d{3,8})$中由分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:

m = re.match(r'^(\d{3})-(\d{3,8})$', '083-8250168')
print(m)
# <_sre.SRE_Match object; span=(0, 11), match='083-8250168'>
 m.group(0)
#'083-8250168'
m.group(1)
# '083'
m.group(2)
# '8250168'
贪婪

正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。比如:

re.match(r'^(\d+)(0*)$', '102300').groups()
# ('102300', '') 由于\d+采用贪婪匹配,直接把后面的0全部匹配了,所以0*就只能匹配空字符串了。

\d+后面加上一个就采用非贪婪匹配了:

re.match(r'^(\d+?)(0*)$', '102300').groups()
# ('1023', '00')

可以使用re.compile()进行预编译,当正则表达式需要多次使用的时候,可以提高效率!
练习
请尝试写一个验证Email地址的正则表达式。版本一应该可以验证出类似的Email:someone@gmail.com、bill.gates@microsoft.com

import re
re_mail = re.compile(r'^[\w]+\.?[\w]+@[\w]+\.com$')
# 字母一个以上 .有一个或者没有 字母一个以上 @ 字母不限 .com

def is_valid_email(addr):
    if re_mail.match(addr):
        return True
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值