【问题标题】:Fetching a certain text from multi-line file从多行文件中获取特定文本
【发布时间】:2019-07-26 17:54:45
【问题描述】:

考虑到文本文件有多个换行符和空格,我想在 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:

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

【问题讨论】:

    标签: python regex regex-lookarounds regex-negation regex-group


    【解决方案1】:

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

    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 指定 . 字符将匹配所有字符,包括换行符

    【讨论】:

    • 谢谢,我可以包含“Route-Details”关键字进行匹配吗?
    • 当然:re.findall(r'(?&lt;=Route-Details).*?(?&lt;=Data: )(.*?)\n', text, re.DOTALL)
    • 感谢您的合作。我可以解释一下匹配和转义是如何工作的吗?
    • 当然,我已经添加了解释。
    • 感谢您的帮助。我去添加的链接进行解释,我没有找到添加的部分“Route-Details”。你能检查一下吗?另外,你能解释一下命令的逻辑吗?
    【解决方案2】:

    我会做类似的事情

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

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

    希望对您有所帮助:)

    【讨论】:

    • 是的,因为获取的块必须具有“Route-Details”关键字,因为有类似的组具有不同的关键字。因此,我必须匹配是否与“Route-Details”相关的数据。我该怎么做?
    【解决方案3】:

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

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

    【讨论】:

    • 只有当port 11 是指定的端口号时才会匹配。我怀疑这是 OP 所期望的行为。
    【解决方案4】:

    当您想在 python 中使用已知侧面的正则表达式检索文本的一部分时,最简单的方法是:

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

    *。将匹配除换行符以外的任意数量的字符,因此在您的情况下,如果您不使用 DOTALL 标志,则可以将换行符用作右侧而不指定它。 不带参数(或 0 作为参数)的 group() 方法返回完全匹配,而不管捕获组。

    group(1) 返回第一个捕获组。在您的情况下,第一个捕获组是一个lookbehind 语句,因此它不会返回任何内容。

    恢复你需要的表达式是:

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

    要将其限制在 Route-Details 块中,您可以编写:

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

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

    ?Data: 将匹配之前匹配后找到的第一个“Data:”

    【讨论】:

    • 非常感谢。
    猜你喜欢
    • 2016-11-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多