从一行中提取特定的数字字符串

时间:2019-08-11 13:23:43

标签: python regex python-3.x

我正在访问的日志文件的行为:

May  1 07:39:30 example-server sshd[61362]: reverse mapping checking getaddrinfo for 37-115-223-100.broadband.kyivstar.net [37.115.223.100] failed - POSSIBLE BREAK-IN ATTEMPT!

May  1 07:42:02 example-server sshd[61698]: reverse mapping checking getaddrinfo for 234.10.13.218.broad.fs.gd.dynamic.163data.com.cn [218.13.10.234] failed - POSSIBLE BREAK-IN ATTEMPT!

我想解析文件并提取短语(“反向映射检查...”和“失败”之前)方括号内的IP地址

我是正则表达式的新手,无法弄清楚该步骤。

另外,每个八位位组<100或> 100的IP地址令人困惑,因为我不能使用[0-9 [0-9](固定的内容)

请帮助我使用任何方法提取该IP地址。

4 个答案:

答案 0 :(得分:2)

此正则表达式应该有效:

\S

+表示没有空格字符,我正在使用([\]]]+)量词来获取带有IP的整个网址,然后捕获方括号内的组,我正在使用它组:

]。它只能捕获尽可能多的非{{1}}字符,因此它将捕获整个IP地址。

答案 1 :(得分:0)

我将按照以下方式进行操作:

import re
text = '''May  1 07:39:30 example-server sshd[61362]: reverse mapping checking getaddrinfo for 37-115-223-100.broadband.kyivstar.net [37.115.223.100] failed - POSSIBLE BREAK-IN ATTEMPT!

May  1 07:42:02 example-server sshd[61698]: reverse mapping checking getaddrinfo for 234.10.13.218.broad.fs.gd.dynamic.163data.com.cn [218.13.10.234] failed - POSSIBLE BREAK-IN ATTEMPT!'''
ips = re.findall(r'(?<=\[)\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}(?=\])',text)
print(ips) # ['37.115.223.100', '218.13.10.234']

请注意,我使用了所谓的r字符串,因此我可以使用单个\进行转义而无需转义。我的模式包括3个主要部分:

  • (?<=\[)是零长度断言,意味着:检查比赛前是否有[[必须转义,因为它具有特殊含义
  • \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}是由1到3个数字(\d)组成的四个数字,这些数字由点(.剪掉(由于.具有特殊含义,因此也需要转义)< / li>
  • (?=\])是零长度断言,表示:检查比赛后是否存在]]也需要转义。

答案 2 :(得分:0)

import re

regex = r"\[[0-9.]+\] failed"

test_str = ("May  1 07:39:30 example-server sshd[61362]: reverse mapping checking getaddrinfo for 37-115-223-100.broadband.kyivstar.net [37.115.223.100] failed - POSSIBLE BREAK-IN ATTEMPT!\n\n"
    "May  1 07:42:02 example-server sshd[61698]: reverse mapping checking getaddrinfo for 234.10.13.218.broad.fs.gd.dynamic.163data.com.cn [218.13.10.234] failed - POSSIBLE BREAK-IN ATTEMPT!")

matches = re.finditer(regex, test_str, re.MULTILINE)
mapping = [ (' failed', ''), ('[', ''), (']', '') ]


for matchNum, match in enumerate(matches, start=1):
    my_string = match.group()
    for k, v in mapping:
        my_string = my_string.replace(k, v)    
    print ("IP : {match}".format(match = my_string))

答案 3 :(得分:0)

在这种简单情况下,我个人反对使用正则表达式,python具有出色的string.split()方法,该方法可以更快,更简单地工作。 为什么只是不

def get_ip(logstr):
  return logstr.split('reverse mapping checking', 1)[1].split('[', 1)[1].split(']', 1)[0]

with open(logfile) as f:
  for line in f:
    if 'reverse mapping checking' in line:
      print(get_ip(line))

很简单-logstr.split('reverse mapping checking', 1)给您两个字符串-在索引为0的“反向映射检查”之前和索引1为之后的字符串。我将分割计数设置为1,建议python不要再次搜索字符串。然后我们用[1]取字符串的第二个,再用[[]进行分割,用[1]取[]之后的值,然后这次用[]进行除数,因为ip之前是[0]。就这样