如何在Python正则代码中正确转换日志的日期时间格式?
如何修改正则代码以得到符合预期的日期时间格式?
我来帮你一步步解决这个问题!先看看现有代码里的核心问题:
- 日期提取后直接用了
date.groups(),得到的是元组(比如('2017', '01', '19')),没有格式化成你要的YYYY-MM-DD样式 - 时间部分的正则
(\d{9}\+\d{4})把整个193739188+0900都匹配出来了,但其实前6位是时分秒(19:37:39),后面三位是毫秒,最后是时区,需要拆分处理
下面是修改后的完整代码,我标注了关键调整点:
import re from csv import writer log_file = '/Users/kiya/Desktop/mysql/ipscan/ip.txt' output_file = '/Users/kiya/Desktop/mysql/ipscan/output.csv' name_to_check = 'MBX_AUTHENTICATION_FAILED' # 优化:把输出文件打开放在循环外,避免每次循环覆盖内容 with open(output_file, 'w') as outfile: csv_writer = writer(outfile) csv_writer.writerow(["Username","Date","Time","Ip_address"]) with open(log_file, encoding="utf-8") as infile: for line in infile: if name_to_check in line: # 提取用户名(保留你的正则,增加空值容错) username_match = re.search(r'(?<=userName=\[)(.*?)(?=\],)', line) username = username_match.group() if username_match else 'N/A' # 提取日期并格式化为YYYY-MM-DD date_match = re.search(r'(?P<year>\d{4})(?P<month>\d{2})(?P<day>\d{2})', line) if date_match: date = f"{date_match.group('year')}-{date_match.group('month')}-{date_match.group('day')}" else: date = 'N/A' # 提取时间:拆分时分秒、毫秒、时区,格式化为HH:MM:SS time_match = re.search(r'(?P<hour>\d{2})(?P<minute>\d{2})(?P<second>\d{2})\d{3}(?P<timezone>\+\d{4})', line) if time_match: # 若需要保留时区,可改成 f"{time} {time_match.group('timezone')}" time = f"{time_match.group('hour')}:{time_match.group('minute')}:{time_match.group('second')}" else: time = 'N/A' # 提取IP地址(增加空值容错) ip_match = re.search(r'(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])', line) ip = ip_match.group() if ip_match else 'N/A' # 写入CSV行 csv_writer.writerow([username, date, time, ip])
关键修改说明:
- 文件操作优化:把输出文件的初始化放在循环外面,避免每次循环打开时覆盖之前的内容。
- 日期格式化:利用正则分组的名称(year/month/day),用f-string拼接成你需要的
YYYY-MM-DD格式,替代原有的元组返回值。 - 时间正则调整:将时间拆分为小时、分钟、秒、毫秒、时区五个部分,只提取前三者拼接成
HH:MM:SS,如果需要保留毫秒或时区,可直接修改time的拼接逻辑。 - 空值容错处理:给每个正则匹配增加判断,避免匹配失败时抛出
AttributeError,未匹配到的字段会返回N/A。
这样修改后,你就能得到类似2017-01-19和19:37:39的预期格式啦!
内容的提问来源于stack exchange,提问作者Katarina Alves
相关产品推荐
相关产品推荐

