我有几个字符串如下所示:
<some_text> TAG[<some_text>@11.22.33.44] <some_text>
我想从这一行获取ip_address并且只获取ip_address。 (为了这个例子,假设ip地址将始终采用这种格式xx.xx.xx.xx)
编辑:恐怕我不清楚。字符串看起来像这样:
<some_text> TAG1[<some_text>@xx.xx.xx.xx] <some_text> TAG2[<some_text>@yy.yy.yy.yy] <some_text>
请注意,'some_text'可以是可变长度。我需要将不同的正则表达式关联到不同的标记,以便在调用r.group()时,将返回ip地址。在上面的例子中,正则表达式不会有所不同,但这是一个不好的例子。
到目前为止,我尝试过的正则表达式已经不足够了。
理想情况下,我想要这样的事情:
r = re.search('(?<=TAG.*@)(\d\d.\d\d.\d\d.\d\d)', line)
其中line的格式为上面指定的格式。但是,这不起作用,因为您需要具有固定宽度的后视断言。
此外,我已尝试过非捕获组:
r = re.search('(?<=TAG\[)(?:.*@)(\d\d.\d\d.\d\d.\d\d)', line)
但是,我不能使用它,因为r.group()将返回some_text@xx.xx.xx.xx
我知道r.group(1)只返回ip地址。不幸的是,我写的脚本要求我的所有正则表达式在调用r.group()后返回正确的结果。
我可以在这种情况下使用什么样的正则表达式?
代码在python中。
注意:所有some_text都可以是可变长度
答案 0 :(得分:2)
尝试re.search('(?<=@)\d\d\.\d\d\.\d\d\.\d\d(?=\])', line)
。
事实上,如果要检查的字符串中唯一出现的xx.xx.xx.xx格式位于这些IP地址部分,re.search('\d\d\.\d\d\.\d\d\.\d\d', line)
可能会为您提供所需的内容。
编辑:正如我的评论中所述,要查找字符串中所需的所有模式,您只需执行re.findall(pattern_to_match, line)
。因此,在这种情况下,re.findall('\d\d\.\d\d\.\d\d\.\d\d', line)
(或更一般地,re.findall('\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}', line)
)。
编辑2:根据您的评论,这应该有效(tagname
是您当前想要的IP地址的标记。)
r = re.search(tagname + '\[.+?@(?P<ip>\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})', line)
然后你就像psmears所说的那样用r.group("ip")
来引用它。
......实际上,有一种简单的方法可以使正则表达式更加简洁。
r = re.search(tagname + r'\[.+?@(?P<ip>(?:\d{1,3}\.?){4})', line)
事实上,你甚至可以这样做:
r = re.findall('(?P<tag>\S+)\[.+?@(?P<ip>(?:\d{1,3}\.?){4})', line)
哪个会返回一个包含标签及其关联IP地址的列表,因此如果您想要从其中找到不同标签的IP地址,则不必重新检查任何一个字符串。相同的字符串。
......事实上,进一步走得更远(更远?),你可以做到以下几点:
r = dict((m.group("tag"), m.group("ip")) for m in re.finditer('(?P<tag>\S+)\[.+?@(?P<ip>(?:\d{1,3}\.?){4})', line))
或者在Python 3中:
r = {(m.group("tag"), m.group("ip")) for m in re.finditer('(?P<tag>\S+)\[.+?@(?P<ip>(?:\d{1,3}\.?){4})', line)}
然后r
将是一个dict,标签为键,IP地址为各自的值。
答案 1 :(得分:1)
你为什么要使用群组或者根本不看?
re.search('TAG\[.*@(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})\]')
有什么问题?
答案 2 :(得分:1)
我认为不可能这样做 - r.group()将始终返回匹配的整个字符串,因此您不得不使用lookbehind,正如您所说的必须是固定宽度。
相反,我建议修改你正在编写的脚本。我猜你有一整套匹配的正则表达式,并且你不想为每一个指定“这个使用r.group(0)”,“这个使用r.group(3) )“等等。
在这种情况下,您可以使用Python的命名组工具:您可以在正则表达式中命名一个组,如下所示:
(?P<name>CONTENTS)
然后检索与r.group("name")
匹配的内容。
我建议你在脚本中做的是:匹配正则表达式,然后测试是否设置了r.group("usethis")
。如果是这样 - 使用那个;如果不是 - 那么像以前一样使用r.group()。
通过在正则表达式中指定组名usethis
,您可以应对这种尴尬的情况 - 但您的其他正则表达不必知道或关心。
答案 3 :(得分:0)
差不多但我觉得你需要在开始时将。*更改为。 *?,因为你可能在一行上有多个TAG(我相信 - 正如示例中所示)
re.search('TAG(\d+)\[.*?@(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})]')
标签ID将位于第一个反向引用中,IP地址将位于第二个反向引用
中