finditer()函数与findall函数类似,但finditer()返回的是一个可迭代的对象。
import re
s = 'This and that'
print(re.findall(r'(Th\w+) and (th\w+)', s, re.I))
print(re.finditer(r'(Th\w+) and (th\w+)', s, re.I).__next__().groups()) #调用返回值
print(re.finditer(r'(Th\w+) and (th\w+)', s, re.I).__next__().group(1))
it = re.finditer(r'(Th\w+)', s, re.I) #生成一个生成器对象
g = it.__next__() #调用
print(g.groups()) #打印出This,以元组的形式
print(g.group(1))
g = it.__next__() #再次调用
print(g.groups()) #打印出that
#将匹配到的内容生产一个列表,列表中包含两个元组
print([g.groups(1) for g in re.finditer(r'(Th\w+)', s, re.I)])
(7)使用sub()和subn()搜索替换
sub()只替换搜索到的内容,subn()不但替换搜索到的内容,并返回替换的次数。
import re
print(re.sub("g.t","have",'I get A, I got B,I gut C')) #对匹配到的单词替换
print(re.subn("g.t","have",'I get A, I got B,I gut C')) #对匹配到的单词替换,并返回替换次数
print(re.sub('[bd]','Y','abcdef'))
print(re.subn('[bd]','Y','abcdef')) #对字符串替换,并打印替换的字符串的的次数
分组和替换的综合应用(替换日期的表示方法):
import re
import time,datetime
day1 = str(datetime.date.today())
print(day1)
#将月/日/年的时间格式转化成“日/月/年”,将r加在左引号之前,主要目的是为了避免转义特殊字符串字符
print(re.sub(r'(\d{1,2})/(\d{1,2})/(\d{2}|\d{4})', r'\2/\1/\3', '05/06/2017'))
print(re.sub(r"(\d{2}|\d{4})-(\d{1,2})-(\d{1,2})", r"\3/\2/\1", day1))
(8)使用split分割字符串
import re
print(re.split('\d+','one1two2three3,for4')) #以匹配到的数字对字符串以“,”进行分割
4、正则表达式的应用
(1)对Linux系统who命令输出内容进行处理
将Linux系统who命令输出结果保存到whodata.txt中:
[root@linuxidc ~]# cat whodata.txt
liu2 :0 2017-04-17 22:10 (:0)
liu2 pts/0 2017-04-17 22:11 (:0)
root pts/1 2017-05-05 03:51(172.16.252.112)
root pts/2 2017-05-05 03:51(172.16.252.112)
root pts/3 2017-05-05 03:52 (172.16.252.112)
对who命令输出的内容进行处理:
import re
f = open('whodata.txt','r')
for line in f:
#对匹配到的行的内容以逗号分隔,将每一行的内容分别存到一个列表中
print(re.split(r'\s\s+',line.rstrip()))
f.close()
使用findall()函数处理win下tasklist命令:
import os
import re
f = os.popen('tasklist /nh', 'r')
for line in f:
print(re.findall(r'([\w.]+(?:[\w]+)*)\s\s+(\d+) \w+\s\s+\d+\s\s+([\d,]+ K)', line.rstrip()))
#读取每一行中自己需要的数据
f.close()
(2)生成用于正则表达式练习的数据
#!/usr/bin/env python
from random import randrange,choice
from stringimport ascii_letters as lc
from sys import maxsize
from time import ctime
tlds = ('com','deu','net','org','gov')
for i in range(randrange(5,11)):
dtint = randrange(maxsize) #生成一个随机数字组
#在属组中取一个6到十位的随机数作为时间戳生成一个日期
dtstr = ctime(int(str(dtint)[0:randrange(6,10)]))
llen = randrange(4,8) #生成一个4-8的随机数字
login = ''.join(choice(lc) for j in range(llen)) #生成邮箱@符号前的字符
dlen = randrange(llen,13)
dom = ''.join(choice(lc) for j in range(dlen)) #生成@后的字符,长度有dlen来决定
#choice(tlds)为在tlds总随机选择一个域名后缀
print('%s::%s@%s.%s::%d-%d-%d' % (dtstr,login,dom,choice(tlds),dtint,llen,dlen))
将上面生成的数据保存到一个文件中用于后面练习:
#!/usr/bin/env python
import re
with open('gendata.txt','r') as f:
for line in f:
patt = '.+(\d+-\d+-\d+)' #为贪婪匹配,匹配前面为任意字符,后面组中为如“5-7-10”的数据
print(re.match(patt, line).group(1))
'''"?"要求正则表达式引擎匹配尽可能少的字符,在"+","*","?"后使用可达到预期效果'''
patt1= '.+?(\d+-\d+-\d+)' #通过"?",匹配到了符合分组中的所有字符串
print(re.match(patt1, line).group(1))