2016-04-21 101 views
1

我是新来的Python,并遵守从具有其出现在文件中的一个元素,它在文件中的频率这样正则表达式来查找匹配列表中的元素

('95.108.240.252', 9) 
文件的项目列表

其主要的IP地址,我收集。我想输出是这样,而不是

IP    Frequency 
95.108.240.252 9 

我试图通过regexing列表项和打印的,但它返回下面的错误,当我尝试TypeError: expected string or bytes-like object

这要做到这一点的地址和频率是我使用做的所有现在的代码:

ips = [] # IP address list 
for line in f: 
    match = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", line) # Get all IPs line by line 
    if match: 
     ips.append(match.group()) # if found add to list 

from collections import defaultdict 
freq = defaultdict(int) 
for i in ips: 
    freq[i] += 1 # get frequency of IPs 

print("IP\t\t Frequency") # Print header 

freqsort = sorted(freq.items(), reverse = True, key=lambda item: item[1]) # sort in descending frequency 
for c in range(0,4): # print the 4 most frequent IPs 
    # print(freqsort[c]) # This line prints the item like ('95.108.240.252', 9) 
    m1 = re.search("\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", freqsort[c]) # This is the line returning errors - trying to parse IP on its own from the list 
    print(m1.group()) # Then print it 

不是想即使解析频率呢,只是想将IP地址为起点

+0

'freqsort [c]'是元组 – rock321987

+0

哪条线会抛出错误BitFlow?正如're.search'导致问题,或者一般哪一行? – DuckPuncher

+0

'('95 .108.240.252',9)'是否出现在一行上 –

回答

1

re.search()的第二个参数应该是字符串,你逝去的tuple。因此,它是产生错误说,它预计stringbuffer

注: -你也需要确保对IP地址有至少4个元素,否则会出现index out of bounds错误

删除最后两行,并用这个代替

print(freqsort[c][0]) 

如果你想坚持你的格式,你可以使用以下但它是没有用的

m1 = re.search(r"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}", freqsort[c][0]) # This is the line returning errors - trying to parse IP on its own from the list 
print(m1.group()) 
+0

更简单的一行比我需要的更好,谢谢。虽然我不明白你的注释 – BitFlow

+0

@BitFlow你正在使用'for c在范围(0,4):'循环中。如果有少于4个元素(IP地址)..它会产生'列表索引超出范围'错误.. – rock321987

+0

4实际上是我的代码中的变量N,并且有70行代替,虽然我注意到它返回当我尝试输入更高的数字时出错类似于'如果N> len(freqsort):sys.exit(2)'工作阻止? 编辑:删除'<''替换'''' – BitFlow

1

改为使用字节对象:

# notice the `b` before the quotes. 
match = re.search(b'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', line) 
+0

返回此错误TypeError:不能在字符串类对象上使用字节模式 – BitFlow

+0

这很奇怪。你是否尝试打印“线路”?它输出什么? – DuckPuncher

+0

这里有一行,有一百多条:'95.108.240.252 - - [14/Feb/2013:00:59:06 +0000]“GET /机器人。txt HTTP/1.1“404 534” - “”Mozilla/5.0(兼容; YandexBot/3.0; + http://yandex.com/bots)“' 这是一条线,因为它出现在我正在阅读的文件中 – BitFlow

0

尝试带有正面和负面查找的正则表达式。

(?<=\(\')(.*)(?=\').*(\d+) 

第一个捕获的组将是您的IP和第二个频率。

+0

我不确定我是否理解,你能说出它会发生什么,它会做什么,或者它会如何影响我已有的? – BitFlow

+0

啊,我刚刚列出了正则表达式,但会按照示例 – Saleem

+0

Saleem,我认为他正在修复'TypeError'。 – DuckPuncher

0

Y您可以同时使用ipaddressCounter在STDLIB,以协助这个...

from collections import Counter 
from ipaddress import ip_address 

with open('somefile.log') as fin: 
    ips = Counter() 
    for line in fin: 
     ip, rest_of_line = line.partition(' ')[::2] 
     try: 
      ips[ip_address(ip)] += 1 
     except ValueError: 
      pass 

print(ips.most_common(4)) 

这也将处理IPv4和IPv6样式地址,并确保他们是技术上是正确的不只是“看”是正确的。使用collections.Counter也会给你一个.most_common()方法,以最频繁的方式自动排序,并将其限制为的数量。