Python正则匹配IP时因部分匹配致索引-1结果错误的修复方法
问题修复:IP与邮箱的精确匹配
问题背景
编写的Python代码意图从all.txt读取IP地址,在email.yaml中找到对应IP的上一行邮箱并输出对应关系,但因re.search的部分匹配特性(如1.1.1.1会匹配到1.1.1.12),导致邮箱匹配错误,仅输出一条错误结果,需修正以得到三个正确的对应关系。
现有代码
import re import smtplib import ssl from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText from email.header import Header from datetime import datetime with open('all.txt', 'r') as names_file: with open('email.yaml', 'r') as emails_file: names = names_file.readlines() emails = emails_file.readlines() for name in names: name = name.strip() for i, email in enumerate(emails): email = re.sub('-', '', email) email = re.sub(' ', '', email) if re.search(name, email): prev_email = emails[i-1].strip() prev_email = re.sub('-', '', prev_email) prev_email = re.sub(' ', '', prev_email) html = html.format(name=name) print(f"Name: {name}, Email: {prev_email}") break
文件内容
all.txt:
1.1.1.1 1.1.1.12 1.1.1.11
email.yaml:
- emailA@gmail.com - 1.1.1.12 - emailB@gmail.com - 1.1.1.1 - emailC@gmail.com - 1.1.1.11
当前输出
Name: 1.1.1.1, Email: emailA@gmail.com
期望输出
Name: 1.1.1.1, Email: emailB@gmail.com Name: 1.1.1.12, Email: emailA@gmail.com Name: 1.1.1.11, Email: emailC@gmail.com
修复方案
核心问题是部分匹配导致的误匹配,以下提供两种高效修复方式:
方案1:预构建IP-邮箱映射字典(推荐)
先遍历email.yaml,将每一组邮箱和对应IP存入字典,后续直接通过IP键查找邮箱,彻底避免正则匹配问题,同时提升查找效率。
修改后代码:
import re # 预构建IP到邮箱的映射字典 ip_email_map = {} with open('email.yaml', 'r') as emails_file: lines = [line.strip() for line in emails_file.readlines()] # 按邮箱+IP的成对结构遍历 for idx in range(0, len(lines), 2): if idx + 1 >= len(lines): break # 清理邮箱和IP的格式(去除-和空格) clean_email = re.sub(r'[- ]', '', lines[idx]) clean_ip = re.sub(r'[- ]', '', lines[idx+1]) ip_email_map[clean_ip] = clean_email # 读取all.txt并输出对应关系 with open('all.txt', 'r') as names_file: for ip_line in names_file.readlines(): target_ip = ip_line.strip() if target_ip in ip_email_map: print(f"Name: {target_ip}, Email: {ip_email_map[target_ip]}") else: print(f"Name: {target_ip}, 未找到对应邮箱")
方案2:修改正则为精确匹配
若需保留原循环结构,将re.search改为精确匹配,同时转义IP中的.(正则中.为通配符)。
修改后核心循环代码:
import re with open('all.txt', 'r') as names_file: with open('email.yaml', 'r') as emails_file: names = names_file.readlines() emails = emails_file.readlines() for name in names: target_ip = name.strip() # 转义IP中的.,避免正则通配符干扰 escaped_ip = re.escape(target_ip) for i, line in enumerate(emails): clean_line = re.sub(r'[- ]', '', line.strip()) # 精确匹配整个字符串 if re.fullmatch(escaped_ip, clean_line): prev_line = emails[i-1].strip() clean_email = re.sub(r'[- ]', '', prev_line) print(f"Name: {target_ip}, Email: {clean_email}") break
验证结果
运行任意一种修复方案,均可得到期望的输出结果:
Name: 1.1.1.1, Email: emailB@gmail.com Name: 1.1.1.12, Email: emailA@gmail.com Name: 1.1.1.11, Email: emailC@gmail.com
内容的提问来源于stack exchange,提问作者Saeed
相关产品推荐
相关产品推荐

