使用Python 3.4解析文本文件并将匹配模式写入另一个文件
我想打开一个文本文件,然后从中找出特定的正则表达式模式。如果找到这个模式,我就把匹配到的内容写到另一个文本文件里。
具体来说,我想从一个IP地址的列表中提取出特定的IP地址。
这个文件可能包含:
10.10.10.10
9.9.9.9
5.5.5.5
6.10.10.10
假设我只想要那些以10结尾的IP地址(我觉得我的正则表达式还不错),我的例子是寻找10.180.42和041.XX的IP地址。但我会根据需要进行调整。
我尝试了几种方法,但都失败得很惨。今天这样的日子让我明白了为什么我从来没有掌握过任何编程语言。不过我决定专注于Python,所以我开始了。
import re
textfile = open("SymantecServers.txt", 'r')
matches = re.findall('^10.180\.4[3,1].\d\d',str(textfile))
print(matches)
这让我得到了空的结果。我不得不把文本文件放在str函数里,否则就出错了。我不知道这样做是否正确。
无论我怎么调整,这个方法都失败了。
f = open("SymantecServers.txt","r")
o = open("JustIP.txt",'w', newline="\r\n")
for line in f:
pattern = re.compile("^10.180\.4[3,1].\d\d")
print(pattern)
#o.write(pattern)
#o.close()
f.close()
我确实有一个方法可以工作,但它返回的是整行内容(包括网络掩码和其他像主机名这样的信息,都是在同一行的文本文件里)。我只想要IP地址。
有没有人能帮我一下,教我怎么读取一个文本文件,如果里面有IP地址的模式,就把完整的IP地址抓取出来,并写入另一个文本文件,这样我就能得到一个只包含我想要的IP地址的文本文件。我已经花了3个小时在这上面,工作也落后了,所以我打算先手动处理第一个文件……
我真的不知道我缺少了什么。抱歉,我还是个新手。
2 个回答
你可能忽略了一点,就是你在使用 re.compile()
这个函数,它在Python中创建了一个正则表达式对象。你忘记去匹配了。
你可以试试:
# This isn't the best way to match IP's, but if it fits for your use-case keep it for now.
pattern = re.compile("^10.180\.4[13].\d\d")
f = open("SymantecServers.txt",'r')
o = open("JustIP.txt",'w')
for line in f:
m = pattern.match(line)
if m is not None:
print "Match: %s" %(m.group(0))
o.write(m.group(0) + "\n")
f.close()
o.close()
这个代码是在编译Python对象,尝试把这一行和编译好的对象进行匹配,然后打印出当前的匹配结果。我可以避免拆分我的匹配结果,但我需要注意匹配的组,所以要用到 group(0)
。
你也可以看看 re.search()
,这也是可以用的。不过如果你用同一个正则表达式运行 search
很多次,使用 compile
会更划算。
另外,我把 f.close() 移到了 for 循环的外面。
这里是它工作的样子:
>>> s = """10.10.10.10
... 9.9.9.9
... 5.5.5.5
... 10.180.43.99
... 6.10.10.10"""
>>> re.findall(r'10\.180\.4[31]\.\d\d', s)
['10.180.43.99']
- 其实你不需要添加行边界,因为你要匹配的是一个非常特定的IP地址。如果你的文件里没有像
'123.23.234.10.180.43.99.21354'
这样奇怪的东西,那就没问题! - 你的
[3,1]
这个写法是匹配3
、1
或者,
,但你不想匹配到逗号;-)
关于你的函数:
r = re.compile(r'10\.180\.4[31]\.\d\d')
with open("SymantecServers.txt","r") as f:
with open("JustIP.txt",'w', newline="\r\n") as o:
for line in f:
matches = r.findall(line)
for match in matches:
o.write(match)
不过如果我是你,我会用下面的方法提取IP:
r = re.compile(r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}')
with open("SymantecServers.txt","r") as f:
with open("JustIP.txt",'w', newline="\r\n") as o:
for line in f:
matches = r.findall(line)
for match in matches:
a, b, c, d = match.split('.')
if int(a) < 255 and int(b) < 255 and int(c) in (43, 41) and int(d) < 100:
o.write(match)
或者还有另一种方法:
r = re.compile(r'(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})')
with open("SymantecServers.txt","r") as f:
with open("JustIP.txt",'w', newline="\r\n") as o:
for line in f:
m = r.match(line)
if m:
a, b, c, d = m.groups()
if int(a) < 255 and int(b) < 255 and int(c) in (43, 41) and int(d) < 100:
o.write(match)
这个方法使用正则表达式将IP地址分成几个部分。