【问题标题】:How to match text and optional repeated identifiers and group them together?如何匹配文本和可选的重复标识符并将它们组合在一起?
【发布时间】:2021-08-08 22:44:20
【问题描述】:

我正在尝试提取一个文本块,后跟一个或多个标识符(由斜杠分隔),并使用 python 中的正则表达式将标识符与文本块分组。

这是一些虚拟示例数据:

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 EX 0-02a
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vestibulum eget vestibulum sapien.
Sed porta, odio id sollicitudin congue
          EX 0-04a

Lorem ipsum dolor sit amet, consectetur adipiscing elit.
Vestibulum eget vestibulum sapien, sed porta, odio id sollicitudin congue
Lorem ipsum dolor sit amet
EX 0-01a / EX 0-05a / EX 0-07a /
EX 0-08a


Lorem ipsum dolor sit amet, 
consectetur adipiscing 
elit.
Vestibulum eget 
vestibulum sapien.
                                                      EX 3-11b

到目前为止,我已经创建了这个正则表达式:

(.*?)(\w{2,4} \d-\d{0,2}\w)

这成功地捕获了文本和一个单数代码,但有些块有多个代码(有时在多行上),并且这些代码没有组合在一起,因为 / 正在被拾取为匹配项。

这是我需要的输出:

[(Lorem ipsum dolor sit amet, consectetur adipiscing elit.), (EX 0-01a / EX 0-02a / EX 0-05b / EX 0-03a)]

正则表达式101:https://regex101.com/r/Wfc4nj/1

【问题讨论】:

  • 在如图所示的数据中,根本不需要正则表达式。 (1) 将文本分成段落:可以使用text.split('\n\n') 或逐行迭代并使用空白行来组织数据。 (2) 在每个段落中,将第一行(文本)与其余部分(您要捕获的代码)分开。 (3) 使用line.split('/') 拆分带有代码的行,并使用strip() 删除不需要的空格。如果实际数据比较复杂,你应该提供一个更充实的例子来说明情况。
  • @FMc - 正如您所提到的,数据不像示例那样结构化,它在整个文本中包含多个换行符(这是从 word 文件中提取的)并且无法保证的换行符以逐行拆分数据。我已更新问题以反映这一点。
  • 为什么示例发生了变化,但 这是我需要的那种输出: 没有改变?而且您还没有提供您在 python 中尝试过的内容!

标签: python regex


【解决方案1】:

您可以重复匹配捕获组中的标识符的模式,并使用 \s+ 匹配 1 个或多个也匹配换行符的空白字符(如果标识符可以跨多行)。

\s*(.+?)\s*(\w{2,4} \d-\d{0,2}\w(?:\s+/\s+\w{2,4} \d-\d{0,2}\w)*)

查看regex demoPython demo

例如

import re

pattern = r"\s*(.+?)\s*(\w{2,4} \d-\d{0,2}\w(?:\s+/\s+\w{2,4} \d-\d{0,2}\w)*)"

s = ("Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
            " EX 0-02a\n"
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
            "Vestibulum eget vestibulum sapien.\n"
            "Sed porta, odio id sollicitudin congue\n"
            "          EX 0-04a\n\n"
            "Lorem ipsum dolor sit amet, consectetur adipiscing elit.\n"
            "Vestibulum eget vestibulum sapien, sed porta, odio id sollicitudin congue\n"
            "Lorem ipsum dolor sit amet\n"
            "EX 0-01a / EX 0-05a / EX 0-07a /\n"
            "EX 0-08a\n\n\n"
            "Lorem ipsum dolor sit amet, \n"
            "consectetur adipiscing \n"
            "elit.\n"
            "Vestibulum eget \n"
            "vestibulum sapien.\n"
            "                                                      EX 3-11b")

print(re.findall(pattern, s, re.S))

输出

[
('Lorem ipsum dolor sit amet, consectetur adipiscing elit.', 'EX 0-02a'),
('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nVestibulum eget vestibulum sapien.\nSed porta, odio id sollicitudin congue', 'EX 0-04a'),
('Lorem ipsum dolor sit amet, consectetur adipiscing elit.\nVestibulum eget vestibulum sapien, sed porta, odio id sollicitudin congue\nLorem ipsum dolor sit amet', 'EX 0-01a / EX 0-05a / EX 0-07a /\nEX 0-08a'), 
('Lorem ipsum dolor sit amet, \nconsectetur adipiscing \nelit.\nVestibulum eget \nvestibulum sapien.', 'EX 3-11b')
]

【讨论】:

  • 不错!这正是我需要的。谢谢。
猜你喜欢
  • 1970-01-01
  • 2015-01-26
  • 2021-01-26
  • 1970-01-01
  • 1970-01-01
  • 2014-01-05
  • 2022-10-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多