簡體   English   中英

我會使用什么樣的正則表達來匹配它?

[英]What kind of regex would I use to match this?

我有幾個字符串,如下所示:

<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都可以是可變長度

嘗試re.search('(?<=@)\\d\\d\\.\\d\\d\\.\\d\\d\\.\\d\\d(?=\\])', line)

實際上,如果只出現xx.xx,則re.search('\\d\\d\\.\\d\\d\\.\\d\\d\\.\\d\\d', line)可以獲得所需的內容。正在檢查的字符串中的xx.xx格式位於這些IP地址部分中。

編輯:正如我的評論中所述,要查找字符串中所有出現的所需模式,您只需執行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)

然后你只需用r.group("ip")來引用它就像psmears所說的那樣。

......實際上,有一種簡單的方法可以使正則表達式更簡潔。

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地址作為相應的值。

你為什么要使用群組或者根本不看? re.search('TAG\\[.*@(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\]')什么問題re.search('TAG\\[.*@(\\d{1,3}\\.\\d{1,3}\\.\\d{1,3}\\.\\d{1,3})\\]')

我認為不可能這樣做 - r.group()將始終返回匹配的整個字符串,因此您不得不使用lookbehind,正如您所說,必須是固定寬度。

相反,我建議修改你正在編寫的腳本。 我猜你有一整套匹配的正則表達式,並且你不想為每一個指定“這個使用r.group(0)”,“這個使用r.group(3) )“等

在這種情況下,您可以使用Python的命名組工具:您可以在正則表達式中命名一個組,如下所示:

(?P<name>CONTENTS)

然后檢索與r.group("name")匹配的r.group("name")

我建議你在腳本中做的是:匹配正則表達式,然后測試是否設置了r.group("usethis") 如果是這樣 - 使用那個; 如果不是 - 那么像以前一樣使用r.group()。

這樣,你可以通過指定組名稱,像這樣難堪的局面應付usethis在正規表達式-但你的其他正則表達式不必知道或關心。

幾乎,但我認為你需要在開始時改變。*。 *? 因為你可能在一行上有多個TAG(我相信 - 正如示例中所示)

re.search('TAG(\d+)\[.*?@(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})]')

標簽ID將位於第一個反向引用中,IP地址將位於第二個反向引用中

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM