【笔记】2022.5.5 正则表达式

0. 正则表达式的便捷性

正则表达式:解决字符串问题的工具(让复杂的字符串问题变得简单的一个工具)

APPLICATION 1 验证输入的手机号是否合法:

tel = '13354627381'


# 方法1:不用正则表达式
def is_tel_num(tel_no: str):
    if len(tel_no) != 11:
        return False

    if tel_no[0] != '1':
        return False

    if tel_no[1] not in '3456789':
        return False

    return tel_no.isdigit()


print(is_tel_num(tel))


# 方法2:用正则表达式
from re import fullmatch


def is_tel_num2(tel_no: str):
    return not fullmatch(r'1[3-9]\d{9}', tel_no) != None


print(is_tel_num(tel))

APPLICATION 2 提取字符串中的数字:

message = '收到回复就234数据jssh 78师傅好看2391金虎送福23刷卡机sshs34'
# 234、78、2391、23、34

# 方法1:普通写法
all_num = []
num_str = ''
for index in range(len(message)):
    if message[index].isdigit():
        num_str += message[index]
    else:
        all_num.append(num_str)
        num_str = ''

all_num.append(num_str)
all_num = [int(x) for x in all_num if x]
print(all_num)


# 方法2:用正则表达式
from re import findall
all_num2 = findall(r'\d+', message)
print(all_num2)

补充:

python中提供正则表达式的方式:r’正则表达式’

js中提供正则表达式的方式:/正则表达式/


2. 匹配类符号

一个正则符号表示一类字符

匹配类符号在正则中的作用:用来要求字符串中某个位置必须是什么样的字符


2.1 普通符号

在正则表达式中表示这个符号本身,对字符串中的字符的要求就是符号本身

RIGHT Example:

# 要求字符串:总共有3个字符,第一个是'a',第二个是'b',第三个是'c'
result = fullmatch(r'abc', 'abc')
print(result)       # <re.Match object; span=(0, 3), match='abc'>

result = fullmatch(r'abc', 'mcd')
print(result)       # None

2.2 句号 .

匹配任意一个字符

RIGHT Example:

# 要求字符串:总共有3个字符,第一个是'a',最后一个是'c',中间可以是任意符号
result = fullmatch(r'a.c', 'aac')
print(result)       # <re.Match object; span=(0, 3), match='aac'>

result = fullmatch(r'a.c', 'a🐴c')
print(result)       # <re.Match object; span=(0, 3), match='a🐴c'>

result = fullmatch(r'..xy', '是sxy')
print(result)       # <re.Match object; span=(0, 4), match='是sxy'>

2.3 \d

匹配一个任意数字

RIGHT Example:

result = fullmatch(r'a\dc', 'a1c')
print(result)       # <re.Match object; span=(0, 3), match='a1c'>

result = fullmatch(r'a\dc', 'a五c')
print(result)       # None

result = fullmatch(r'\d{3}', '111')
print(result)       # <re.Match object; span=(0, 3), match='111'>

2.4 \s

匹配任意一个空白字符

空白字符包括:空格、\n、\t、\r

RIGHT Example:

result = fullmatch(r'a\sb', 'a b')
print(result)       # <re.Match object; span=(0, 3), match='a b'>

result = fullmatch(r'a\sb', 'a\tb')
print(result)       # <re.Match object; span=(0, 3), match='a\tb'>

result = fullmatch(r'a\sb', 'a\nb')
print(result)       # <re.Match object; span=(0, 3), match='a\nb'>

result = fullmatch(r'a\sb', 'asb')
print(result)       # None

2.5 \w

匹配任意一个数字、字母、下划线或者中文

RIGHT Example:

result = fullmatch(r'a\wb', 'a雪b')
print(result)       # <re.Match object; span=(0, 3), match='a雪b'>

result = fullmatch(r'a\wb', 'a2b')
print(result)       # <re.Match object; span=(0, 3), match='a2b'>

result = fullmatch(r'a\wb', 'a*b')
print(result)       # None

2.6 \大写字母

与相应的小写字母的功能相反

\D:匹配任意一个非数字字符

\S:匹配任意一个非空白字符

\W:匹配任意一个非"字母、数字、下划线和中文"

RIGHT Example:

result = fullmatch(r'a\Db', 'a2b')
print(result)       # None

result = fullmatch(r'a\Db', 'acb')
print(result)       # <re.Match object; span=(0, 3), match='acb'>

result = fullmatch(r'a\Sb', 'a b')
print(result)       # None

result = fullmatch(r'a\Sb', 'a雪b')
print(result)       # <re.Match object; span=(0, 3), match='a雪b'>

2.7 [字符集]

匹配字符集中任意一个字符

注意:一个[]只能匹配一个字符

(1)[多个普通符号]:例如[abc12],在’a’、‘b’、‘c’、‘1’、'2’五个符号中任意一个可以匹配

RIGHT Example 1:

result = fullmatch(r'1[xyz]2', '1x2')
print(result)       # <re.Match object; span=(0, 3), match='1x2'>

result = fullmatch(r'1[xyz]2', '1y2')
print(result)       # <re.Match object; span=(0, 3), match='1y2'>

result = fullmatch(r'1[xyz]2', '1u2')
print(result)       # None

(2)[包含\开头的特殊符号]:例如[mn\d]、[m\dn]、[\dmn],要求是m或者n或者任意一个数字

RIGHT Example 2:

result = fullmatch(r'a[mn\d]b', 'anb')
print(result)       # <re.Match object; span=(0, 3), match='anb'>

result = fullmatch(r'a[mn\d]b', 'a9b')
print(result)       # <re.Match object; span=(0, 3), match='a9b'>

(3)[字符串1-字符串2]:例如[a-z],要求是任意一个小写字母

​ [a-zA-Z],要求是任意一个字母

​ [2-9a-z],要求是2到9或者是任意一个小写字母

​ [\u4e00-\u9fa5],要求是任意一个中文

​ [\u4e00-\u9fa5\dabc]

注意:[]中如果减号不在两个字符之间,就不能表示"谁到谁",那他就是个普通符号

RIGHT Example 3:

result = fullmatch(r'1[a-z]2', '1h2')
print(result)       # <re.Match object; span=(0, 3), match='1h2'>

result = fullmatch(r'1[a-z][a-z]2', '1hx2')
print(result)       # <re.Match object; span=(0, 4), match='1hx2'>

result = fullmatch(r'a[\u4e00-\u9fa5]b', 'a还b')
print(result)       # <re.Match object; span=(0, 3), match='a还b'>

result = fullmatch(r'a[一-龥]b', 'a十b')
print(result)       # <re.Match object; span=(0, 3), match='a十b'>

result = fullmatch(r'a[\u4e00-\u9fa5\dxy]b', 'a3b')
print(result)       # <re.Match object; span=(0, 3), match='a3b'>

result = fullmatch(r'a[az-]b', 'a-b')
print(result)       # <re.Match object; span=(0, 3), match='a-b'>

result = fullmatch(r'a[az-]b', 'avb')
print(result)       # None

2.8 [ ^字符集]

匹配不在字符集中的任意一个字符

RIGHT Example:

result = fullmatch(r'1[^xyz]2', '1x2')
print(result)       # None

result = fullmatch(r'1[^xyz]2', '182')
print(result)       # <re.Match object; span=(0, 3), match='182'>

result = fullmatch(r'1[^\dab]2', '182')
print(result)       # None

result = fullmatch(r'1[^\dab]2', '1z2')
print(result)       # <re.Match object; span=(0, 3), match='1z2'>

3. 匹配次数


3.1 星号*

匹配0次或者多次(任意次数)。例如:

a *:a出现任意次数

\d *:任意多个数字

[abc] *:任意多个"a或者b或者c"

RIGHT Example:

result = fullmatch(r'a*b', 'aab')
print(result)       # <re.Match object; span=(0, 3), match='aab'>

result = fullmatch(r'a*b', 'b')
print(result)       # <re.Match object; span=(0, 1), match='b'>

result = fullmatch(r'\d*b', '49b')
print(result)       # <re.Match object; span=(0, 3), match='49b'>

result = fullmatch(r'[A-Z]*b', 'ASFb')
print(result)       # <re.Match object; span=(0, 4), match='ASFb'>

3.2 加号+

匹配1次或者多次(至少1次)

RIGHT Example:

result = fullmatch(r'a+b', 'aab')
print(result)       # <re.Match object; span=(0, 3), match='aab'>

result = fullmatch(r'a+b', 'b')
print(result)       # None

3.3 问号?

匹配0次或者1次

RIGHT Example:

result = fullmatch(r'-?123', '-123')
print(result)       # <re.Match object; span=(0, 4), match='-123'>

result = fullmatch(r'-?123', '--123')
print(result)       # None

result = fullmatch(r'[+-]?123', '+123')
print(result)       # <re.Match object; span=(0, 4), match='+123'>

result = fullmatch(r'[+-]?123', '+-123')
print(result)       # None

3.4 大括号{}

(1){n}:匹配n次

RIGHT Example:

result = fullmatch(r'\d{3}abc', '111abc')
print(result)       # <re.Match object; span=(0, 6), match='111abc'>

result = fullmatch(r'\d{3}abc', '1111abc')
print(result)       # None

(2){m,n}:匹配m到n次

RIGHT Example:

result = fullmatch(r'\d{2,5}abc', '1111abc')
print(result)       # <re.Match object; span=(0, 7), match='1111abc'>

result = fullmatch(r'\d{2,5}abc', '111111abc')
print(result)       # None

(3){m,}:匹配至少m次

RIGHT Example:

result = fullmatch(r'\d{2,}abc', '1111111111abc')
print(result)       # <re.Match object; span=(0, 13), match='1111111111abc'>

result = fullmatch(r'\d{2,}abc', '1abc')
print(result)       # None

(4){,n}:匹配至多n次

RIGHT Example:

result = fullmatch(r'\d{,5}abc', '1111abc')
print(result)       # <re.Match object; span=(0, 7), match='1111abc'>

result = fullmatch(r'\d{,5}abc', '11111111abc')
print(result)       # None

3.5 贪婪和非贪婪

在匹配次数不确定的时候,匹配模式分为贪婪和非贪婪两种。解释:

匹配次数不确定:*、+、?、{m,n}、{m,}、{,n}

贪婪和非贪婪:在次数不确定的情况下,对应的字符串在不同次数下有多种匹配结果,贪婪取最多次数对应的结果,非贪婪取最少次数对应的结果。(前提是匹配成功有多种情况)

贪婪:*、+、?、{m,n}、{m,}、{,n}

非贪婪:*?、+?、??、{m,n}?、{m,}?、{,n}?

RIGHT Example 1:

# 贪婪
result = fullmatch(r'\d+', '26373')
print(result)       # <re.Match object; span=(0, 5), match='26373'>

result = search(r'\d+', '环球网会丢千万别打2643阿斯达373askdgasf')
print(result)       # <re.Match object; span=(9, 13), match='2643'>

# 非贪婪
result = fullmatch(r'\d+?', '26373')
print(result)       # <re.Match object; span=(0, 5), match='26373'>

result = search(r'\d+?', '环球网会丢千万别打2643阿斯达373askdgasf')
print(result)       # <re.Match object; span=(9, 10), match='2'>

RIGHT Example 2:

# 'amnb' -> 2, 'amnbxnxyb' -> 6, 'amnbxnxyb盛世b' -> 9
result = search(r'a.*b', r'环球网会丢千万别打amnbxnxyb盛世b-2---===')
print(result)       # <re.Match object; span=(9, 21), match='amnbxnxyb盛世b'>

result = search(r'a.*?b', r'环球网会丢千万别打amnbxnxyb盛世b-2---===')
print(result)       # <re.Match object; span=(9, 13), match='amnb'>

RIGHT Example 3:

html = '<body><span>开始!</span><p>你是好嘛</p><a>百度</a><p>hello world!</p><body>'
result = search(r'<p>.*</p>', html)
print(result)
# <re.Match object; span=(22, 61), match='<p>你是好嘛</p><a>百度</a><p>hello world!</p>'>

html = '<body><span>开始!</span><p>你是好嘛</p><a>百度</a><p>hello world!</p><body>'
result = search(r'<p>.*?</p>', html)
print(result)
# <re.Match object; span=(22, 33), match='<p>你是好嘛</p>'>

4. 分组

在正则中用括号将正则中的一部分内容括起来就形成了一个分组


4.1 整体操作

RIGHT Example:

# 匹配两个字母两个数字的结构重复3次,'mn78jh56lm89'
result = fullmatch(r'[a-zA-Z]{2}\d\d[a-zA-Z]{2}\d\d[a-zA-Z]{2}\d\d', 'mn78jh56lm89')
print(result)       # <re.Match object; span=(0, 12), match='mn78jh56lm89'>

4.2 重复

在正则中:\N可以重复\N所在的位置的前面的第N个分组匹配到的内容

RIGHT Example:

# 匹配:'23abc23'、'59abc59':成功,'23abc56':失败
result = fullmatch(r'(\d\d)abc\1', '23abc23')
print(result)       # <re.Match object; span=(0, 7), match='23abc23'>

result = fullmatch(r'(\d\d)abc\1', '23abc56')
print(result)       # None

result = fullmatch(r'(\d{3})([a-z]{2})-\2\1', '958mn-mn958')
print(result)       # <re.Match object; span=(0, 11), match='958mn-mn958'>

result = fullmatch(r'(((\d{2})[A-Z]{3})[a-z]{2})-\2-\1-\3', '12EEEbn-12EEE-12EEEbn-12')
print(result)
# <re.Match object; span=(0, 24), match='12EEEbn-12EEE-12EEEbn-12'>

4.3 捕获

获取正则匹配结果中的部分内容

RIGHT Example:

result = findall(r'\d\d', '爱德华我IQ2法师讲方法23凯撒奖的aa123,大萨达1233==ieu13')
print(result)       # ['23', '12', '12', '33', '13']

result = findall(r'[a-z](\d\d)', '爱德华我IQ2法师讲方法23凯撒奖的aa123,大萨达1233==ieu13')
print(result)       # ['12', '13']

5. 分支

正则1|正则2:先用正则1进行匹配如果匹配成功就直接成功,如果匹配失败再用正则2匹配,如果匹配成功就成功,如果失败就失败

RIGHT Example:

# 匹配:abc后面是两个任意数字或者两个任意的大写字母'abc34'、'abcKJ'
result = fullmatch(r'abc(\d\d|[A-Z]{2})', 'abc23')
print(result)       # <re.Match object; span=(0, 5), match='abc23'>

6. 检测类符号(了解)

检测类符号不是匹配符号,不会要求某个位置必须是什么样的字符,而是检测某个位置是否符合相关要求


6.1 \b

检测是否是单词边界

单词边界:可以用来将两个单词区分开的符号,例如:空白字符、标点符号、字符串开头、字符串结尾

RIGHT Example:

result = findall(r'\d+', '数据23324najsd84是2039,安吉撒  235adwq,235 稳得无群46AS')
print(result)       # ['23324', '84', '2039', '235', '235', '46']

result = findall(r'\b\d+', '数据23324najsd84是2039,安吉撒  235adwq,235 稳得无群46AS')
print(result)       # ['235', '235']

6.2 \B

检查的是否是非单词边界


6.3 ^

检测是否是字符串开头([]外面)


6.4 $

检测是否是字符串结尾


7. 转义符号

正则中的转义符号是指在本身就具备特殊功能的符号前加\,让它本身具备的特殊功能消失变成一个普通符号

WRONG Example :

# (1)写一个正则匹配一个小数:如2.3

result = fullmatch(r'\d+.\d+', '3a14')
print(result)       # <re.Match object; span=(0, 4), match='3a14'>

# (2)写一个正则匹配两位数+两位数

result = fullmatch(r'\d\d+\d\d', '33+14')
print(result)       # None

# (3)写一个正则表达式匹配括号中两个汉字:(护具)

result = fullmatch(r'([一-龥]{2})', '(护具)')
print(result)       # None

RIGHT Example:

# (1)写一个正则匹配一个小数:如2.3

result = fullmatch(r'\d+\.\d+', '3a14')
print(result)       # None

result = fullmatch(r'\d+\.\d+', '3.14')
print(result)       # <re.Match object; span=(0, 4), match='3.14'>

# (2)写一个正则匹配两位数+两位数

result = fullmatch(r'\d\d\+\d\d', '33+14')
print(result)       # <re.Match object; span=(0, 5), match='33+14'>

# (3)写一个正则表达式匹配括号中两个汉字:(护具)

result = fullmatch(r'\([一-龥]{2}\)', '(护具)')
print(result)       # <re.Match object; span=(0, 4), match='(护具)'>

补充:独立存在有特殊意义的符号,放到[]中特殊功能会直接消失变成一个普通符号,例如+、*、.、?、)、(等

RIGHT Example:

result = fullmatch(r'[.+*?$]ab[.]c', '*ab.c')
print(result)       # <re.Match object; span=(0, 5), match='*ab.c'>

8. re模块

re模块是python用来支持正则表达式的一个模块

re模块中提供了各种和正则相关的函数:fullmatch、search、findall、match、split、sub等


8.1 常用函数


8.1.1 fullmatch(正则表达式, 字符串)

用整个字符串和正则表达式匹配,如果匹配成功返回匹配对象,匹配失败返回None

RIGHT Example:

result = fullmatch(r'\d{3}', '728')
print(result)       # <re.Match object; span=(0, 3), match='728'>

8.1.2 match(正则表达式, 字符串)

匹配字符出纳开头,如果匹配成功返回匹配对象,匹配失败返回None

RIGHT Example:

result = match(r'\d{3}', '72823421rwdasfcasf')
print(result)       # <re.Match object; span=(0, 3), match='728'>

8.1.3 search(正则表达式, 字符串)

匹配字符串中第一个满足正则的子串,如果匹配成功返回匹配对象,匹配失败返回None

RIGHT Example:

result = search(r'\d{3}', '手机号728奥术大师多234rwdasfcasf')
print(result)       # <re.Match object; span=(3, 6), match='728'>

8.1.4 findall(正则表达式, 字符串)

获取字符串中所有满足正则的子串,返回值是列表,列表中的元素是匹配到的字符串

RIGHT Example:

result = findall(r'\d{3}', '手机号728奥术大师多m234rwda888sfcasf')
print(result)       # ['728', '234', '888']

result = findall(r'[a-z]\d{3}', '手机号728奥术大师多m234rwda888sfcasf')
print(result)       # ['m234', 'a888']

result = findall(r'[a-z](\d{3})', '手机号728奥术大师多m234rwda888sfcasf')
print(result)       # ['234', '888']

result = findall(r'([a-z])(\d{3})', '手机号728奥术大师多m234rwda888sfcasf')
print(result)       # [('m', '234'), ('a', '888')]

8.1.5 finditer(正则表达式, 字符串)

获取字符串中所有满足正则的子串,返回一个迭代器,迭代器中的元素是匹配对象

RIGHT Example:

result = finditer(r'\d{3}', '手机号728奥术大师多m234rwda888sfcasf')
print(list(result))
# [<re.Match object; span=(3, 6), match='728'>, <re.Match object; span=(12, 15), match='234'>, <re.Match object; span=(19, 22), match='888'>]

result = finditer(r'([a-z])(\d{3})', '手机号728奥术大师多m234rwda888sfcasf')
print(list(result))
# [<re.Match object; span=(11, 15), match='m234'>, <re.Match object; span=(18, 22), match='a888'>]

8.1.6 split(正则表达式, 字符串, N)

将字符串中所有满足正则的子串作为切割点对字符串进行切割,返回一个列表,列表中的元素是字符串。N代表切割次数

RIGHT Example:

result = split(r'\d{3}', '手机号728奥术大师多m234rwda888sfcasf')
print(result)       
# ['手机号', '奥术大师多m', 'rwda', 'sfcasf']

result = split(r'[abc]', '手机a号728奥b术大c师多m234rwda888sfcasf')
print(result)       
# ['手机', '号728奥', '术大', '师多m234rwd', '888sf', '', 'sf']

result = split(r'[abc]', '手机a号728奥b术大c师多m234rwda888sfcasf', 3)
print(result)       
# ['手机', '号728奥', '术大', '师多m234rwda888sfcasf']

8.1.7 sub(正则, 字符串1, 字符串2, N)

将字符串2中所有满足正则的子串全部替换成字符串1。N代表替换次数

RIGHT Example:

message = '暗红色的a萨克的b阿斯加德巴萨卡c阿北师大b驱蚊器翁a阿富汗玩法c王企鹅厒'
result = sub(r'[abc]', '++', message)
print(result)
# 暗红色的++萨克的++阿斯加德巴萨卡++阿北师大++驱蚊器翁++阿富汗玩法++王企鹅厒

message = '暗红色的47189471萨克的124阿斯加德巴萨卡132739阿北师大121231驱蚊器翁123阿富汗玩法124王企鹅厒'
result = sub(r'\d+', '0', message)
print(result)
# 暗红色的0萨克的0阿斯加德巴萨卡0阿北师大0驱蚊器翁0阿富汗玩法0王企鹅厒

message = '暗红色的47189471萨克的124阿斯加德巴萨卡132739阿北师大121231驱蚊器翁123阿富汗玩法124王企鹅厒'
result = sub(r'\d+', '0', message, 2)
print(result)
# 暗红色的0萨克的0阿斯加德巴萨卡132739阿北师大121231驱蚊器翁123阿富汗玩法124王企鹅厒

8.2 匹配对象


8.2.1 获取匹配结果对应的字符串

RIGHT Example:

result = search(r'([a-z]{2})-(\d{3})', '手机号ag-728奥术大师多234rwdasfcasf')
print(result)       # <re.Match object; span=(3, 9), match='ag-728'>

# a.获取整个正则匹配到的字符串:匹配对象.group()
r1 = result.group()
print(r1)       # ag-728

# b.获取某个分组匹配到的结果:匹配对象.group(N)
r2 = result.group(1)
print(r2)       # ag

r3 = result.group(2)
print(r3)       # 728

8.2.2 获取匹配结果在原字符串中的位置信息

RIGHT Example:

result = search(r'([a-z]{2})-(\d{3})', '手机号ag-728奥术大师多234rwdasfcasf')
print(result)       # <re.Match object; span=(3, 9), match='ag-728'>

r1 = result.span()
print(r1)       # (3, 9)

r2 = result.span(2)
print(r2)       # (6, 9)

8.3 参数


8.3.1 单行匹配和多行匹配

多行匹配的时候’.‘不能和’\n’进行匹配(默认):flags=re.M、?m

单行匹配的时候’.‘能和’\n’进行匹配:flags=re.S、?s

RIGHT Example:

# 设置多行匹配
result = fullmatch(r'a.c', 'a\nc', flags=M)
print(result)       # None

result = fullmatch(r'(?m)a.c', 'a\nc')
print(result)       # None

# 设置单行匹配
result = fullmatch(r'a.c', 'a\nc', flags=S)
print(result)       # <re.Match object; span=(0, 3), match='a\nc'>

result = fullmatch(r'(?s)a.c', 'a\nc')
print(result)       # <re.Match object; span=(0, 3), match='a\nc'>

8.3.2 忽略大小写

默认情况下大写字母和小写字母是不能匹配的,忽略大小写以后大写字母就可以和对应的小写字母匹配:flags=I、?i

RIGHT Example:

result = fullmatch(r'abc', 'aBc', flags=I)
print(result)  # <re.Match object; span=(0, 3), match='aBc'>

result = fullmatch(r'(?i)12[a-c]', '12B')
print(result)  # <re.Match object; span=(0, 3), match='12B'>

8.3.3 既忽略大小写又要单行匹配

方法:flags=re.I|re.S、(?si)

RIGHT Example:

result = fullmatch(r'abc.12', 'aBc\n12', flags=I|S)
print(result)       # <re.Match object; span=(0, 6), match='aBc\n12'>

result = fullmatch(r'(?is)abc.12', 'aBc\n12')
print(result)       # <re.Match object; span=(0, 6), match='aBc\n12'>

  • 4
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Sprite.Nym

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值