如何使用正则表达式从多行数据中获取必要的信息?

How to grep necessary info from multi-line data using regex?

||/ software                                   version                                          some_text    Description
+++-======================================-===================================================-============-===============================================================================
AA  SOFTWARE1                                   1.1.1.1-UBUNTU                                  GHGFHGFH     Description1
AA  SOFTWARE2                                   1.1.1.2-UBUNTU_HGSFHF                           JGJHGKGK     Description2
BB  SOFTWARE3                                   1.2.3.4.5                                       JHGJHGJG     Description3

以上是存储在字符串中的示例文本格式。这可能有多达 1000 行。其中,需要提取软件和相应的版本详细信息。

方法 1:根据新行拆分并根据 space 拆分每行并捕获列表中的第二项和第三项(不是很好的方法)

方法二:使用正则表达式编译存储。

我认为第二种方法很好。

regex = r".*(AA|BB)\s+(.*)\s+(.*)\s+(.*)\s+(.*)"
matches = re.finditer(regex, test_str, re.MULTILINE)

如何从每一行中 grep 这些软件和版本详细信息并将它们存储在字典或任何其他格式中?

如果您想要 2 个捕获组,其中软件的值(可以包含空格)在第 1 组中,版本在第 2 组中,您可以使用这些值之间空白字符数的差异(假设软件确实不包含比字段之间更多的空白字符)

^(?:AA|BB)\s{2,}(\S.*?)\s{2,}(\S+)
  • ^ 字符串开头
  • (?:AA|BB) 在非捕获组中匹配 AABB
  • \s{2,} 匹配 2 个或更多空白字符
  • (\S.*?) 第 1 组 捕获单个非空白字符,后跟尽可能少的任何字符
  • \s{2,} 匹配 2 个或更多空白字符
  • (\S+) 第 2 组,捕获 1+ 个非空白字符

看到一个regex demo.

如果你想创建一个以第 1 组为键,第 2 组为值的字典:

import re

pattern = r"^(?:AA|BB)\s{2,}(\S.*?)\s{2,}(\S+)"

s = ("||/ software                                   version                                          some_text    Description\n"
            "+++-======================================-===================================================-============-===============================================================================\n"
            "AA  SOFTWARE1 this is some text                                   1.1.1.1-UBUNTU                                  GHGFHGFH     Description1\n"
            "AA  SOFTWARE2                                   1.1.1.2-UBUNTU_HGSFHF                           JGJHGKGK     Description2\n"
            "BB  SOFTWARE3                                   1.2.3.4.5                                       JHGJHGJG     Description3")


dct = dict(re.findall(pattern, s, re.M))
print(dct)

输出

{'SOFTWARE1 this is some text': '1.1.1.1-UBUNTU', 'SOFTWARE2': '1.1.1.2-UBUNTU_HGSFHF', 'SOFTWARE3': '1.2.3.4.5'}

您还可以使模式更具体一些,以匹配版本列的示例数据:

^(?:AA|BB)\s{2,}(\S.*?)\s{2,}(\d+(?:\.\d+)*(?:-\w+)?)

Regex demo