当给你一大堆文本信息,让你提取其中的指定数据时,可以使用正则来实现。例如:提取文本中的邮箱和手机号
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
phone_list = re.findall("1[3|5|8|9]\d{9}", text)
print(phone_list)
1. 字符相关
-
hqss 匹配文本中的hqss
import re
text = "你好hqss,阿斯顿发hqssasd 阿士大夫能接受的hqssff"
data_list = re.findall("hqss", text)
print(data_list) # ['hqss', 'hqss'] 可用于计算字符串中某个字符出现的次数
-
[abc]
匹配a或b或c 字符。
import re
text = "你2b好hqss,阿斯顿发hqssasd 阿士大夫a能接受的hffbbqpqaceissff"
data_list = re.findall("[abc]", text)
print(data_list) # ['b', 'a', 'a', 'a', 'b', 'b', 'c']
import re
text = "你2b好hqss,阿斯顿发ahqssasd 阿士大夫a能接受的hffbbqpqcceissff"
data_list = re.findall("q[abc]", text)
print(data_list) # ['qa', 'qc']
-
[^abc]
匹配除了abc以外的其他字符。
import re
text = "你hffbbqpqcceissff"
data_list = re.findall("[^abc]", text)
print(data_list) # ['你', 'h', 'f', 'f', 'q', 'p', 'q', 'e', 'i', 's', 's', 'f', 'f']
-
[a-z]
匹配a~z的任意字符( [0-9]也可以 )。
import re
text = "hqssrootrootadmin"
data_list = re.findall("t[a-z]", text)
print(data_list) # ['tr', 'ta']
-
.
代指除换行符以外的任意字符。 (注意,最前面是一个点.)
import re
text = "hqssraotrootadmin"
data_list = re.findall("r.o", text)
print(data_list) # ['rao', 'roo']
import re
text = "hqssraotrootadmin"
data_list = re.findall("r.+o", text) # 贪婪匹配
print(data_list) # ['raotroo']
import re
text = "hqssraotrootadmin"
data_list = re.findall("r.+?o", text) # 非贪婪匹配
print(data_list) # ['rao']
-
\w
代指字母或数字或下划线(汉字)。
import re
text = "北京武沛alex齐北 京武沛alex齐"
data_list = re.findall("武\w+x", text)
print(data_list) # ['武沛alex', '武沛alex']
-
\d
代指数字
import re
text = "root-ad32min-add3-admd1in"
data_list = re.findall("d\d", text)
print(data_list) # ['d3', 'd3', 'd1']
import re
text = "root-ad32min-add3-admd1in"
data_list = re.findall("d\d+", text)
print(data_list) # ['d32', 'd3', 'd1']
-
\s
代指任意的空白符,包括空格、制表符等。
import re
text = "root admin add admin"
data_list = re.findall("a\w+\s\w+", text)
print(data_list) # ['admin add']
2. 数量相关
-
*
重复0次或更多次
import re
text = "他是大B个,确实是个大2B。"
data_list = re.findall("大2*B", text)
print(data_list) # ['大B', '大2B']
-
+
重复1次或更多次
import re
text = "他是大B个,确实是个大2B,大3B,大66666B。"
data_list = re.findall("大\d+B", text)
print(data_list) # ['大2B', '大3B', '大66666B']
-
?
重复0次或1次
import re
text = "他是大B个,确实是个大2B,大3B,大66666B。"
data_list = re.findall("大\d?B", text)
print(data_list) # ['大B', '大2B', '大3B']
-
{n}
重复n次
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("151312\d{5}", text)
print(data_list) # ['15131255789']
-
{n,}
重复n次或更多次
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("\d{9,}", text)
print(data_list) # ['442662578', '15131255789']
-
{n,m}
重复n到m次
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("\d{10,15}", text)
print(data_list) # ['15131255789']
3. 括号(分组)
-
提取数据区域
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("15131(2\d{5})", text)
print(data_list) # ['255789']
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来15131266666呀"
data_list = re.findall("15(13)1(2\d{5})", text)
print(data_list) # [ ('13', '255789') ]
import re
text = "楼主太牛逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("(15131(2\d{5}))", text)
print(data_list) # [('15131255789', '255789')]
-
获取指定区域 + 或条件
import re
text = "楼主15131root太牛15131alex逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("15131(2\d{5}|r\w+太)", text)
print(data_list) # ['root太', '255789']
import re
text = "楼主15131root太牛15131alex逼了,在线想要 442662578@qq.com和xxxxx@live.com谢谢楼主,手机号也可15131255789,搞起来呀"
data_list = re.findall("(15131(2\d{5}|r\w+太))", text)
print(data_list) # [('15131root太', 'root太'), ('15131255789', '255789')]
4. 起始和结束
上述示例中都是去一段文本中提取数据,只要文本中存在即可。
但,如果要求用户输入的内容必须是指定的内容开头和结尾,比就需要用到如下两个字符。
-
^
开始 -
$
结束
import re
text = "啊442662578@qq.com我靠"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list) # []
import re
text = "442662578@qq.com"
email_list = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
print(email_list) # ['442662578@qq.com']
这种一般用于对用户输入数据格式的校验比较多,例如:
import re
text = input("请输入邮箱:")
email = re.findall("^\w+@\w+.\w+$", text, re.ASCII)
if not email:
print("邮箱格式错误")
else:
print(email)
5. 特殊字符
由于正则表达式中 * . \ { } ( )
等都具有特殊的含义,所以如果想要在正则中匹配这种指定的字符,需要转义,例如:
import re
text = "我是你{5}爸爸"
data = re.findall("你{5}爸", text)
print(data) # []
import re
text = "我是你{5}爸爸"
data = re.findall("你\{5\}爸", text)
print(data)
6. re模块
python中提供了re模块,可以处理正则表达式并对文本进行处理。
-
findall,获取匹配到的所有数据
import re
text = "dsf130429191912015219k13042919591219521Xkk"
data_list = re.findall("(\d{6})(\d{4})(\d{2})(\d{2})(\d{3})([0-9]|X)", text)
print(data_list) # [('130429', '1919', '12', '01', '521', '9'), ('130429', '1959', '12', '19', '521', 'X')]
-
match,从起始位置开始匹配,匹配成功返回一个对象,未匹配成功返回None
import re
text = "大小逗2B最逗3B欢乐"
data = re.match("逗\dB", text)
print(data) # None
# data.group()的功能就是只展示出匹配到的一个值
import re
text = "逗2B最逗3B欢乐"
data = re.match("逗\dB", text)
if data:
content = data.group() # "逗2B"
print(content)
# data.groups()的功能就是可以输出所括号出的多个值
import re
text = "逗2B最逗3B欢乐"
data = re.match("(逗)\d(B)", text)
if data:
content = data.groups() # "逗2B"
print(content) # ('逗', 'B')
import re
text = "逗2B最逗3B欢乐"
data = re.match("(逗)\d(B)", text)
if data:
v1, v2 = data.groups() # "逗2B"
print(v1, v2) # '逗' 'B'
-
search,浏览整个字符串去匹配第一个,未匹配成功返回None
import re
text = "大小逗2B最逗3B欢乐"
data = re.search("逗\dB", text)
if data:
print(data.group()) # "逗2B"
-
sub,替换匹配成功的位置
import re
text = "逗2B最逗3B欢乐"
data = re.sub("\dB", "沙雕", text)
print(data) # 逗沙雕最逗沙雕欢乐
import re
text = "逗2B最逗3B欢乐"
data = re.sub("\dB", "沙雕", text, 1)
print(data) # 逗沙雕最逗3B欢乐
-
split,根据匹配成功的位置分割
import re
text = "逗2B最逗3B欢乐"
data = re.split("\dB", text)
print(data) # ['逗', '最逗', '欢乐']
import re
text = "逗2B最逗3B欢乐"
data = re.split("\dB", text, 1)
print(data) # ['逗', '最逗3B欢乐']
-
finditer
import re
text = "逗2B最逗3B欢乐"
data = re.finditer("\dB", text)
for item in data:
print(item.group())
import re
text = "逗2B最逗3B欢乐"
data = re.finditer("(?P<xx>\dB)", text) # 命名分组
for item in data:
print(item.groupdict())
text = "dsf130429191912015219k13042919591219521Xkk"
data_list = re.finditer("\d{6}(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})\d{3}[\d|X]", text)
for item in data_list:
info_dict = item.groupdict()
print(info_dict)
至此,Python 相关的正则表达式已总结到此,如有不当之处 欢迎批评指正!