摘要
书接前文:
01-《零基础编程——起步并搭建Python环境及图书推荐》
06-《零基础编程——Python模块项目打包发布PyPI,pip可安装》
本文将分析模式匹配和正则表达式。不管是Python、Java、C#等主流编程语言,还是SQL数据处理,都离不开正则表达式,进行快速字符串匹配或者截取。如果通过字符串匹配的方式去截取数据,将是一个非常麻烦的事情。如果通过正则表达式去匹配则非常容易快捷高效。
主要内容:
一 正则表达式案例
1-案例:手机号码校验
手机号码规则
2-案例-电话号码查找
二 正则表达式语法
0-字符分类
1-正则表达式分组
2-正则表达式管道
3-正则表达式可选匹配
4-正则表达式匹配零次或者多次
5-正则表达式匹配一次或者多次
6-正则表达式匹配指定次数n-m次
7-建立自己的字符分类
8-插入字符^开始和美元符号$结束
9-通配字符 .
10-点-星 匹配字符串
三 正则表达式 match()与search()
1-re.match()
2-re.search()
3-findall()
4-忽略大小写
四 总结
一 正则表达式案例
1-案例:手机号码校验
正则表达式:
import re
#创建正则表达式对象
regexObj = re.compile(r'^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4(?:(?:10|4[01])\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$')
phone = regexObj.match('15989114102')
if phone:
print(phone.group()+'是有效手机号码')
else:
print('匹配失败,不是有效手机号码')
phone = re.match(pattern='^(?:\+?86)?1(?:3(?:4[^9\D]|[5-9]\d)|5[^3-6\D]\d|7[28]\d|8[23478]\d|9[578]\d)\d{7}$',string='15989114102')
print(phone.group()+'是中国移动')
例如:
import re
#创建正则表达式对象
regexObj = re.compile(r'^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4(?:(?:10|4[01])\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$')
phone = regexObj.match('15989114102')
if phone:
print(phone.group()+'是有效手机号码')
else:
print('匹配失败,不是有效手机号码')
phone = re.match(pattern='^(?:\+?86)?1(?:3(?:4[^9\D]|[5-9]\d)|5[^3-6\D]\d|7[28]\d|8[23478]\d|9[578]\d)\d{7}$',string='15989114102')
print(phone.group()+'是中国移动')
参考电话号码规则:
https://github.com/VincentSit/ChinaMobilePhoneNumberRegex/blob/master/POSIX-CN.md
匹配所有号码(手机卡 + 数据卡 + 上网卡)
^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4(?:(?:10|4[01])\d{3}|[68]\d{4}|[579]\d{2}))\d{6}$
匹配所有支持短信功能的号码(手机卡 + 上网卡)
^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[0-35-9]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|6[2567]\d{2}|4[579]\d{2})\d{6}$
手机卡
匹配所有
^(?:\+?86)?1(?:3\d{3}|5[^4\D]\d{2}|8\d{3}|7(?:[235-8]\d{2}|4(?:0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|66\d{2})\d{6}$
匹配中国移动
^(?:\+?86)?1(?:3(?:4[^9\D]|[5-9]\d)|5[^3-6\D]\d|7[28]\d|8[23478]\d|9[578]\d)\d{7}$
匹配中国联通
^(?:\+?86)?1(?:3[0-2]|[578][56]|66|96)\d{8}$
匹配中国电信
^(?:\+?86)?1(?:3(?:3\d|49)\d|53\d{2}|8[019]\d{2}|7(?:[37]\d{2}|40[0-5])|9[0139]\d{2})\d{6}$
匹配中国广电
^(?:\+?86)?192\d{8}$
匹配北京船舶通信导航有限公司(海事卫星通信)
^(?:\+?86)?1749\d{7}$
工业和信息化部应急通信保障中心(应急通信)
^(?:\+?86)?174(?:0[6-9]|1[0-2])\d{6}$
虚拟运营商
匹配所有
^(?:\+?86)?1(?:7[01]|6[257])\d{8}$
匹配中国移动
^(?:\+?86)?1(?:65\d|70[356])\d{7}$
匹配中国联通
^(?:\+?86)?1(?:70[4789]|71\d|67\d)\d{7}$
匹配中国电信
^(?:\+?86)?1(?:70[012]|62\d)\d{7}$
物联网数据卡
匹配所有
^(?:\+?86)?14(?:[14]0|41|[68]\d)\d{9}$
匹配中国移动
^(?:\+?86)?14(?:4[01]|8\d)\d{9}$
匹配中国联通
^(?:\+?86)?146\d{10}$
匹配中国电信
^(?:\+?86)?1410\d{9}$
上网卡
匹配所有
^(?:\+?86)?14[579]\d{8}$
匹配中国移动
^(?:\+?86)?147\d{8}$
匹配中国联通
^(?:\+?86)?145\d{8}$
匹配中国电信
^(?:\+?86)?149\d{8}$
2-案例-电话号码查找
import re
regexObj = re.compile(r'\d\d\d-\d\d\d-\d\d\d\d')#校验规则,\d表示一位数字
phone = regexObj.search(r'他的电话号码是 400-400-4000')
if phone:
print(phone.group())
#运行结果
400-400-4000
二 正则表达式语法
字符分类
\d 0-9的任意数字
\D 除了0-9以外的任何字符
\w 任何
\W 除了任何
1-正则表达式分组
import re
regexObj = re.compile(r'(\d\d\d)-(\d\d\d-\d\d\d\d)')#校验规则,\d表示一位数字,()表示分组
phone = regexObj.search(r'他的电话号码是 400-400-4000')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
#运行结果:
400
400-4000
400-400-4000
400-400-4000
2-正则表达式管道
#管道 |
import re
regexObj = re.compile(r'(\d\d(1|2))-(\d\d\d-\d\d\d\d)')#校验规则,\d表示一位数字,()表示分组,|表示管道
phone = regexObj.search(r'他的电话号码是 400-400-4000 或者401-400-4000 或者 402-400-4000')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
#运行结果
#管道 |...
401
1
401-400-4000
401-400-4000
3-正则表达式可选匹配
#?可选 Bat(wo)?man > Batman 或者Batwoman
import re
regexObj = re.compile(r'(\d\d(1|2))?\d\d\d-\d\d\d\d')#?表示可选
phone = regexObj.search(r'他的电话号码是 400-400-4000 或者401-401-4001')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
else:
print('没有匹配上')
#运行结果
None
None
400-4000
400-4000
4-正则表达式匹配零次或者多次
#()*匹配0次或者多次
import re
regexObj = re.compile(r'(\d)*(1|2)-(\d)*-(\d)*')#?表示可选
phone = regexObj.search(r'他的电话号码是 4010-400-4000 或者41101-401-4001')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
else:
print('没有匹配上')
5-正则表达式匹配一次或者多次
#()+匹配1次或者多次
import re
regexObj = re.compile(r'(4)+(\d)*(1|2)-(\d)*-(\d)*')#?表示可选
phone = regexObj.search(r'他的电话号码是 4010-400-4000 或者31101-401-4001 或者41101-401-4001')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
else:
print('没有匹配上')
6-正则表达式匹配指定次数n-m次
#(){n,m}匹配指定n-m次
import re
regexObj = re.compile(r'(4)+(\d){3}(1|2)-(\d){3}-(\d){1,5}')#?表示可选
phone = regexObj.search(r'他的电话号码是 4010-400-4000 或者31101-401-4001 或者41101-401-40015或者41101-401-40014')
if phone:
print(phone.group(1))
print(phone.group(2))
print(phone.group(0))
print(phone.group())
else:
print('没有匹配上')
7-建立自己的字符分类
import re
regexObj = re.compile(r'([^4\D])+')#不是以4开头的数字
phone = regexObj.search(r'他的电话号码567841是 4010-400-4000 或者31101-401-4001 或者41101-401-40015或者41101-401-40014')
if phone:
print(phone.group())
else:
print('没有匹配上')
[]表示自己选用的字符分类,[^..]表示非
8-插入字符^开始和美元符号$结束
import re
regexObj = re.compile(r'^hello')#以hello 开头 ^
phone = regexObj.search(r'x hello world,他的电话号码567841是 4010-400-4000 或者31101-401-4001 或者41101-401-40015或者41101-401-40014')
if phone:
else:
print('没有匹配上')
#####
phone = regexObj.search(r'hello world,他的电话号码567841是 4010-400-4000 或者31101-401-4001 或者41101-401-40015或者41101-401-40014')
if phone:
print(phone.group())
#####
import re
regexObj = re.compile(r'\d$')#最后一位数字
regexObj = re.compile(r'\d+$')#最后一组数字
phone = regexObj.search(r'hello world,他的电话号码567841是 5, 4010-400-4000 或者31101-401-4001 或者41101-401-40015或者41101-401-40014 8888')
if phone:
print(phone.group())
else:
print('没有匹配上')
#####
import re
regexObj = re.compile(r'^\d+$')#以数字开始并结束
phone = regexObj.search(r'1225104')
if phone:
print(phone.group())
else:
print('没有匹配上')
9-通配字符 .
通配表示一位用 .表示
import re
regexObj = re.compile(r'^\d+.$')#以数字开始并最后一位任意字符结束
phone = regexObj.search(r'1225104x')
if phone:
print(phone.group())
else:
print('没有匹配上')
10-点-星 匹配字符串
匹配所有字符串
import re
regexObj = re.compile(r'电话号码是:(.*)或者(.*)')# 匹配所有字符
phone = regexObj.search(r'电话号码是:123441或者14621')
if phone:
print(phone.group(1))
print(phone.group(2))
else:
print('没有匹配上')
三 正则表达式 match()与search()
1-re.match()
re.match()的概念是从头匹配一个符合规则的字符串,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None。包含的参数如下:
pattern: 正则模型
string : 要匹配的字符串
falgs : 匹配模式
match() 方法一旦匹配成功,就是一个match object对象,而match object对象有以下方法:
2-re.search()
re.search()#函数会在字符串内查找模式匹配,只要找到第一个匹配然后返回,如果字符串没有匹配,则返回None。
- match()函数只检测RE是不是在string的开始位置匹配,
- search()会扫描整个string查找匹配
- match()只有在0位置匹配成功的话才有返回,如果不是开始位置匹配成功的话,match()就返回none
- 两者都有函数:
group() 返回被 RE 匹配的字符串
start() 返回匹配开始的位置
end() 返回匹配结束的位置
span()返回一个元组包含匹配 (开始,结束) 的位置
3-findall()
等同于group(),但是返回的是字符串列表
4-忽略大小写
re.IGNORECASE
四 总结
掌握正则表达式匹配模式的写法,能够可以顺利按照自己的规则匹配数据并且截取数据。熟悉匹配的通配符号和规则。