正则表达式(PY高级编程系列)

正则表达式

需要引入re模块

思考题一

判断多行字符串, 判断哪一行是符合手机号码

import re

cont = '''
aesdf
17811011234
aa1a3hi233rhi3
87156340
affa124564531346546
afa19454132135
'''

cont = '17811011234abc'

# 判断多行字符串, 判断哪一行是符合手机号码

# 编译一个正则表达式
# r 元字符串 内部有转义字符等不进行转换
pattern = re.compile(r'1[3-9]\d{9}')  # 匹配手机号 | 编译对象
result = pattern.search(cont)  # 只会返回匹配第一个结果 如果没有匹配成功返回None | 从整个字符串的任意位置开始匹配

# span 找到匹配的下标位 起始和结束 | 换行+回车算2个字符
print(pattern, result)
print(result.group(0))   # grouo(0) 获得匹配的第一组数据的结果 | 字符串
print(result.span(0))   # grouo(0) 获得匹配的第一组数据的下标 | 元祖

# cont = '17811011234abc' 能匹配
result = pattern.match(cont)  # 从字符串的第一个字符开始匹配 如果第一个字符不匹配就返回None
print(pattern, result)
print(result.group(0))  # 0 可以忽略
print(result.span(0))

正则表达式(PY高级编程系列)

元字符

import re
# 元字符
# . 任意字符(除了换行符) | 匹配任意一个
result = re.match(r'.', 'a')  # 可以
result = re.match(r'.', '7')  # 可以
result = re.match(r'.', '^')  # 可以
result = re.match(r'.', '\n')  # 不可以
result = re.match(r'.', '\r')  # 可以
result = re.match(r'.', '\t')  # 可以
result = re.match(r'.', ' ')  # 可以

# [] 区间集合 可以匹配任意在中一个
# \d 匹配 0-9数字 [0-9]
# \D 非数字 [^0-9] | 在中括号内 ^ 表示非
# \s 空白字符 空格 tab 换行 回车 [\t\n\r\f\v] | \v 垂直制表符 \f 换页符
# \S 非空白字符
# \w 匹配单词字符 [a-zA-Z0-9_]
# \W 匹配非单词字符 非数字字母下划线

result = re.match(r'\d', '7')   # 0-9
result = re.match(r'\d', 'a')
result = re.match(r'[0-9]', '7')
result = re.match(r'[0-46-9]', '5')  # 0-4 与 6-9 不包括 5
result = re.match(r'[0-46-9]', '4')
result = re.match(r'[0-46-9]', '9')
result = re.match(r'[0469]', '6')   # 0469 其他都不行
result = re.match(r'[hH]', 'h')   # Hh 其他都不行
result = re.match(r'天空\d', '天空8号发射成功')
if result is not None:
    print('匹配成功')
    print(result.group())
else:
    print('匹配不成功')

正则表达式(PY高级编程系列)

转义字符 反斜线 \

path = r'I:\AIoT智能物联网工程师\AIoT智能物联网\PY高级\PY高级编程\学习代码\3'  # 正常的需要加双反斜线表 一条反斜线

result = re.match(r'I:\\', path)  # 反斜线不能作结束 就算加了 r 必须加2条反斜线
if result is not None:
    print('匹配成功')
    print(path, result.re, result.group())
else:
    print('匹配不成功')

正则表达式(PY高级编程系列)

数量长度

# 表示数量
# * 0次或多次
# + 1次或多次
# ? 0次或1次
# {m} 出现m次
# {m,} 至少出现m次, 可以更多次
# {m,n} 出现m~n次范围

# 首字母大写 后接 0~多个小写字母
resultItems = []
pattern = r'[A-Z][a-z]*'
resultItems.append(re.match(pattern, 'En'))
resultItems.append(re.match(pattern, 'E'))
resultItems.append(re.match(pattern, 'English'))

# 变量名 字母下划线开头 后接之怒数字下滑线
pattern = r'[a-zA-Z_]\w*'
resultItems.append(re.match(pattern, '_name1'))
resultItems.append(re.match(pattern, 'name1'))
resultItems.append(re.match(pattern, '1name1'))

# 0~99
pattern = r'^\d\d?$'  # 需要用到 ^ $
pattern = r'^\d{0,2}$'  # 也是需要
resultItems.append(re.match(pattern, '0'))
resultItems.append(re.match(pattern, '10'))
resultItems.append(re.match(pattern, '54'))
resultItems.append(re.match(pattern, '99'))
resultItems.append(re.match(pattern, '107'))  # 这个如果去除 ^ $ 也能匹配 匹配2个数字

# 匹配密码
# 至少8位最多20 字母数字下划线, 无其他符号
pattern = r'^\w{8,20}$'
resultItems.append(re.match(pattern, '012345'))
resultItems.append(re.match(pattern, '012345678'))
resultItems.append(re.match(pattern, '~012C34a5678'))
resultItems.append(re.match(pattern, '_012C34a5678'))



print('-' * 80)

for result in resultItems:
    if result is not None:
        print(result.string, result.re, result.group(), '匹配成功')
    else:
        print('匹配不成功')
    
    

正则表达式(PY高级编程系列)

匹配163邮箱

# 匹配163邮箱 | 6~18个字符,可使用字母、数字、下划线,需要以字母开头
resultItems = []
pattern = r'^[a-zA-Z]\w{5,17}@163.com$'  # 前面占用一个字符 5~17

cont = '''
awhahlf@163.com
affafafafaaaaaaaaaaaaaaaa@163.com
afa_@163.com
225afafaf@163.com
aaaa____@qq.com
aaaa____@163.com
'''

for _ in cont.split('\n'):
    resultItems.append(re.match(pattern, _))

print('-' * 80)

for result in resultItems:
    if result is not None:
        print(result.string, result.re, result.group(), '匹配成功')
    else:
        print('匹配不成功')

正则表达式(PY高级编程系列)

匹配边界

print('-' * 80)

pattern = r'^[a-zA-Z]\w{5,17}@163.com$'  # 前面占用一个字符 5~17 | 前面有空格则不匹配

search = re.search(pattern, cont, re.MULTILINE)  # 表示多行匹配 re.MULTILINE
if search is not None:
    print(search.group())

print('-' * 80)

pattern = r'[^\d]'  # 数字取反 | 需要加中括号
resultItems = [re.match(pattern, '12345'), re.match(pattern, 'a12345')]
pattern = r'^\d'
resultItems.append(re.match(pattern, '12345'))
resultItems.append(re.match(pattern, 'a12345'))
pattern = r'.*\bchangsha\b.*'
resultItems.append(re.match(pattern, 'I love changsha too'))
resultItems.append(re.match(pattern, 'I love changshanan too'))
pattern = r'.*changsha\B.*'
resultItems.append(re.match(pattern, 'I love changsha too'))
resultItems.append(re.match(pattern, 'I love changshanan too'))
for result in resultItems:
    if result is not None:
        print(result.string, result.re, result.group(), '匹配成功')
    else:
        print('匹配不成功')

正则表达式(PY高级编程系列)

分组

# 分组
# | 或者 匹配任意一边表达式 不能贪婪模式
# 0~100数字
resultItems = []
pattern = r'^[1-9]?\d$|100$'
resultItems.append(re.match(pattern, '0'))
resultItems.append(re.match(pattern, '8'))
resultItems.append(re.match(pattern, '08'))
resultItems.append(re.match(pattern, '10'))
resultItems.append(re.match(pattern, '47'))
resultItems.append(re.match(pattern, '100'))
resultItems.append(re.match(pattern, 'a100'))
resultItems.append(re.match(pattern, '1000'))
resultItems.append(re.match(pattern, '01000'))
resultItems.append(re.match(pattern, '101'))
resultItems.append(re.match(pattern, '789'))



# 网易邮箱 这里就不是用中括号
pattern = r'^[a-zA-Z]\w{5,17}@(163|126).com$'  # 前面占用一个字符 5~17 | 前面有空格则不匹配

cont = '''
awhahlf@163.com
affafafafaaaaaaaaaaaaaaaa@163.com
afa_@163.com
225afafaf@163.com
aaaa____@126.com
aaaa____@163.com
'''

for _ in cont.split('\n'):
    resultItems.append(re.match(pattern, _))


        
 
# 匹配html的 <h1>任何内容</h1>
resultItems = []
pattern = r'<([a-zA-Z0-9]+)>.*</\1>'
resultItems.append(re.match(pattern, '<h1>这是标题</h1>'))
resultItems.append(re.match(pattern, '<div>这是div</div>'))
resultItems.append(re.match(pattern, '<div>这是错误的</p>'))

# 网页嵌套标签
pattern = r'<(?P<n1>\w+)><(?P<n2>\w+)>.*</(?P=n2)></(?P=n1)>'
resultItems.append(re.match(pattern, '<div><p>这是嵌套的</p></div>'))

for result in resultItems:
    if result is not None:
        print(result.string, result.re, result.group(), '匹配成功')
    else:
        print('匹配不成功')


正则表达式(PY高级编程系列)
正则表达式(PY高级编程系列)

高级用法

# 高级用法

cont = '''
awhahlf@163.com
affafafafaaaaaaaaaaaaaaaa@163.com
afa_@163.com
225afafaf@163.com
aaaa____@126.com
aaaa____@163.com
'''

# 需要小括号扩住整个 否则只会匹配返回163和126
result = re.findall(r'(^[a-zA-Z]\w{5,17}@(163|126).com$)', cont, re.MULTILINE)
print(result)

for k, (a, b) in enumerate(result):
    print(k, a, b)

# sub
"""
针对匹配结果再二次处理
返回repl字符串或者调用repl函数而得到的字符串。如果没有找到模式,则返回字符串不变
需求:将匹配到的阅读次数加1
"""

print(re.sub(r'\d+', '189', 'python = 188'))  # 正则替换
print(re.sub(r'\d+', lambda _: str(int(_.group()) + 1), 'python = 188'))  # 回调函数的话返回是个对象 | 计算需要int 返回需要str

# split 切割
string = 'hello, world, beijing.'
print(re.split(r'\W+', string))

string = 'info:xiaoZhang 33 shandong'
print(re.split(r':| ', string))

'''
1、验证账号是否合法(字母开头,允许5-16字节,允许字母数字下划线)。
2、验证密码是否合法(以字母开头,长度在6~18之间,只能包含字母、数字和下划线)
3、匹配是否全是汉字:
4、验证日期格式(2020-09-10)
5、验证身份证号码。
'''

resultItems = []
pattern = r'^[a-zA-Z]\w{4,15}$'
resultItems.append(re.match(pattern, 'ab9_7cde'))
resultItems.append(re.match(pattern, '_abc_de'))
resultItems.append(re.match(pattern, '8abc_de'))
pattern = r'^[a-zA-Z]\w{5,17}$'
resultItems.append(re.match(pattern, 'ab9_7cde'))
pattern = r'^[\u4e00-\u9fa5]+$'
resultItems.append(re.match(pattern, '中文'))
# [1000-9999]-[01-12]-[01-31]
pattern = r'^\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$'
resultItems.append(re.match(pattern, '2021-11-11'))

for result in resultItems:
    if result is not None:
        print(result.string, result.re, result.group(), '匹配成功')
    else:
        print('匹配不成功')

# 太复杂了
# (?:(?:([1-9]\d{5}(?:18|19|(?:[23]\d))\d{2}(?:(?:0[1-9])|(?:10|11|12))(?:(?:[0-2][1-9])|10|20|30|31)\d{3}[0-9Xx])(?!\d))

# 贪婪或不贪婪 默认贪婪 匹配字符多 加? 非贪婪
string = 'this is my tel:188-8888-9999'
result = re.match(r'(.+?)(\d{3,4}-\d{4}-\d{4})', string)  # 问号可以不加
if result is not None:
    print(result.string, result.re, result.groups(), '匹配成功')
else:
    print('匹配不成功')

正则表达式(PY高级编程系列)

上一篇:git的基本命令


下一篇:如何删除git所有提交历史,如何在不删除本地仓库文件的情况下删除远程仓库文件