ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

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

2021-11-25 20:30:57  阅读:139  来源: 互联网

标签:编程 正则表达式 pattern PY append re result resultItems match


正则表达式

需要引入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))

元字符

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('匹配不成功')

转义字符 反斜线 \

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('匹配不成功')

数量长度

# 表示数量
# * 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('匹配不成功')
    
    

匹配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('匹配不成功')

匹配边界

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('匹配不成功')

分组

# 分组
# | 或者 匹配任意一边表达式 不能贪婪模式
# 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('匹配不成功')



高级用法

# 高级用法

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('匹配不成功')

标签:编程,正则表达式,pattern,PY,append,re,result,resultItems,match
来源: https://blog.csdn.net/weixin_63272654/article/details/121546466

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有