引言
一个小任务中需要将多个数据段中的最新版本信息提取出来,用到了正则表达式提取数据,有些坑,特此记录。
1.非贪婪匹配和零宽度负回顾后发断言
先看代码
import re
listVersion=[]
fileText='PRS-7000风电场-SZ142372_低压-20170702新版本PRS-7000风电场-SZ142372_低压-150102'
matchV=re.findall(r"((PRS-700U|PRS-7000).+?(?<!SZ)(\d{8}|\d{7}|\d{6}))", fileText, re.MULTILINE)
print(matchV)
for matchVersion in matchV:
listVersion.append(matchVersion[0])
print(listVersion)
输出:
[('PRS-7000风电场-SZ142372_低压-20170702', 'PRS-7000', '20170702'), ('PRS-7000风电场-SZ142372_低压-150102', 'PRS-7000', '150102')]
['PRS-7000风电场-SZ142372_低压-20170702', 'PRS-7000风电场-SZ142372_低压-150102']
- 正则
((PRS-700U|PRS-7000).+?(?<!SZ)(\d{8}|\d{7}|\d{6}))
中间的.+?
用到了非贪婪匹配,即懒惰匹配,匹配尽可能少的字符,避免了将两条信息匹配成一条(?<!SZ)
用到了零宽度负回顾后发断言,来断言此位置的前面不能匹配SZ
,避免将SZ开头的编号匹配为六位日期。
当然,日期的正则这里没有更具体,比如判断范围、闰年等。- 如输出结果所示,正则表达式的findall函数以列表形式返回全部能匹配的子串,匹配了所有()分组,遍历取第一个,即最外层()的匹配
re.MULTILINE
表示多行匹配
2.文件读写
读文件:
with open(DATA_FILE) as input_file:
for line in input_file:
Index, fileName, fileType, creatTime, fileRow, fileText = line.split(';')
print(Index+','+fileName+','+fileText)
...
写文件:
with open(STORED_FILE, 'w') as output_file:
str_list = [line + '\n' for line in outputText] # 在list中加入换行符
output_file.writelines(str_list)