从多行文件中获取特定文本

Fetching a certain text from multi-line file

考虑到文本文件有多个换行符和空格,我想使用 python 中的 Regex 包过滤文件中的特定文本。该文件可能有多个数据块,但唯一需要的是带有特定关键字的数据块。在我的问题中,它应该属于包含 "Route-Details" 关键字的组。

假设文件(sample.txt)如下所示。

.
.
.
 Host1<-->Host2 Con. ID:         0x0fc2f0d9  (abc123)
  Con. Information:
     [Gw]  Route-Details 
        R-Code:      0xaaaa (1a2) Route-Details
        Router-ID:     0x21       (a4)  [Gw] 
        Path-Code:    0x00e   (15)
        Data: 123-abcd.djsjdkks www.somesite. port 11

Coded info
                   aa aa aa aa aa aa aa aa   1111-aaa
                   aa aa aa aa aa aa aa aa   1111-aaa
.
.
.

这是我写的

import re
with open("sample.txt", "r") as fl:
    in_file= fl.read()

(re.search('(?<=Route-Details).* Data:', in_file,re.DOTALL).group())

我希望得到这个。

123-abcd.djsjdkks www.somesite. port 11

不过,我明白了。

R-Code:      0xaaaa (1a2) Route-Details
        Router-ID:     0x21       (a4)  [Gw] 
        Path-Code:    0x00e   (15)
        Data:

我想知道我是否可以获得简化和详细的解决方案。 非常感谢您的帮助。

我会做类似的事情

re.search('(?=Data: ).*\n', infile, re.DOTALL).group()

我认为您的问题是您的表达式试图匹配从 'Route-Details' 到 'Data:' 的所有内容。

希望对您有所帮助:)

您可以使用积极的后视和捕获组:

re.findall(r'(?<=Data: )(.*?)\n', text)

产量:

['123-abcd.djsjdkks www.somesite. port 11']

此外,您可以尝试以下方法来包含您指定的 Route-Details 条件:

re.findall(r'(?<=Route-Details).*?(?<=Data: )(.*?)\n', text, re.DOTALL)

详细解释见here。此外,re.DOTALL 指定 . 字符将匹配所有字符,包括换行符

这将解决这个问题,我已经测试过了。 它给出的输出与您预期的相同:

import re
with open("sample.txt", "r") as fl:
    in_file= fl.read()
    print(re.search('(?<=Data: ).* port 11', in_file, re.DOTALL).group())

如果您想在 python 中使用正则表达式检索具有已知侧翼的文本的一部分,最简单的方法是:

re.search('left_flanking_text(*.)right_flanking_text', text_to_search_into).group(1)

*。将匹配任意数量的字符,但换行符,所以在你的情况下,如果你不使用 DOTALL 标志,你可以使用换行符作为右侧而不指定它。 不带参数的 group() 方法(或 0 作为参数)returns 完全匹配,无论捕获组如何。

group(1) returns 第一个捕获组。在你的例子中,第一个捕获组是一个回顾语句,所以它 returns 什么都没有。

恢复你需要的表达式是:

re.search('Data:(.*)', in_file).group(1)

要限制在Route-Details块中,可以这样写:

re.search('Route-Details[\S\s]*?Data:(.*)', in_file).group(1)

[\S\s]* 将匹配任何字符(包括新行)

?Data: 将匹配在前面的匹配项

之后找到的第一个'Data:'