Python 带可选中间短语的多行字符串匹配器

Python 带可选中间短语的多行字符串匹配器,python,regex,multiline,formatted-input,Python,Regex,Multiline,Formatted Input,我想抓取分布在两行之间的文本 例如: PO Number Dept.number 4000813852 7 我想获得订单号4000813852 它类似于基于表的数据,但在整个文档的上下文中似乎是普通文本 我使用了re.MULTILINE如r'PO编号。*\n[0-9]+' 在这种情况下,这不是最好的解决办法,因为也许 PO数< /强>中间为 Invoice Number PO Number Dept.number 123456666 4000813852 7 您可以在启用两个捕获组

我想抓取分布在两行之间的文本

例如:

PO Number Dept.number
4000813852 7
我想获得订单号4000813852 它类似于基于表的数据,但在整个文档的上下文中似乎是普通文本

我使用了
re.MULTILINE
r'PO编号。*\n[0-9]+'

在这种情况下,这不是最好的解决办法,因为也许<强> PO数< /强>中间为

Invoice Number PO Number Dept.number
123456666     4000813852  7

您可以在启用两个捕获组和
re.DOTALL
选项的情况下执行此操作。该表达式假定您感兴趣的数字是文本中仅有的10位数字

表达方式是:

(PO\sNumber).*(\d{10})
Python代码段:

import re

first_string = """PO Number Dept.number
4000813852 7"""

second_string = """Invoice Number PO Number Dept.number
123456666     4000813853  7"""

PO_first = re.search(r'(PO\sNumber).*(\d{10})',first_string,re.DOTALL)
print(PO_first.group(1)+" "+PO_first.group(2))

PO_second = re.search(r'(PO\sNumber).*(\d{10})',second_string,re.DOTALL)
print(PO_second.group(1)+" "+PO_second.group(2))
输出:

PO Number 4000813852
PO Number 4000813853

您可以在启用两个捕获组和
re.DOTALL
选项的情况下执行此操作。该表达式假定您感兴趣的数字是文本中仅有的10位数字

表达方式是:

(PO\sNumber).*(\d{10})
Python代码段:

import re

first_string = """PO Number Dept.number
4000813852 7"""

second_string = """Invoice Number PO Number Dept.number
123456666     4000813853  7"""

PO_first = re.search(r'(PO\sNumber).*(\d{10})',first_string,re.DOTALL)
print(PO_first.group(1)+" "+PO_first.group(2))

PO_second = re.search(r'(PO\sNumber).*(\d{10})',second_string,re.DOTALL)
print(PO_second.group(1)+" "+PO_second.group(2))
输出:

PO Number 4000813852
PO Number 4000813853
使用单个正则表达式:

data="""PO Number Dept.number
    4000813852 7
    Invoice Number PO Number Dept.number
    123456666     4000813852  7
    """

re.findall(r"(PO Number)\s*Dept.number\s*(?:(?:\d+)\s+(\d+)|(\d+))\s+\d",data)
Out: 
[('PO Number', '', '4000813852'), ('PO Number', '4000813852', '')]
我不使用re.MULTILINE,因为\s也匹配换行符。

使用单个正则表达式:

data="""PO Number Dept.number
    4000813852 7
    Invoice Number PO Number Dept.number
    123456666     4000813852  7
    """

re.findall(r"(PO Number)\s*Dept.number\s*(?:(?:\d+)\s+(\d+)|(\d+))\s+\d",data)
Out: 
[('PO Number', '', '4000813852'), ('PO Number', '4000813852', '')]

我不使用re.MULTILINE,因为\s也匹配换行符。

后一种情况未指定,并且与regex不匹配-您可能不得不猜测哪个数字属于PO-我们需要大量数据才能匹配它。您使用正则表达式捕获的文本太多,因为您不使用捕获组。编写基于行/基于列的解析器,并将从包含PO编号的完整行开始到下一行结束的部分提供给它line@ahmed这些解决方案对你有用吗?如果是这样,考虑接受答案,看看如何做到这一点。您唯一的麻烦是在“采购订单编号”和\d+之间为“部门编号”添加一个可选的额外表达式。实际上,除非您可以将“采购订单编号为10位,部门编号为1-3”等特殊知识应用于多行正则表达式,否则@PatrickArtner是正确的。首先,从第一行捕获字段名。然后,从第二行中找出您想要的字段。后一种情况是未指定的,并且与regex不匹配-您可能不得不猜测哪个数字属于PO-我们需要大量数据来匹配它。您使用正则表达式捕获的文本太多,因为您不使用捕获组。编写基于行/基于列的解析器,并将从包含PO编号的完整行开始到下一行结束的部分提供给它line@ahmed这些解决方案对你有用吗?如果是这样,考虑接受答案,看看如何做到这一点。您唯一的麻烦是在“采购订单编号”和\d+之间为“部门编号”添加一个可选的额外表达式。实际上,除非您可以将“采购订单编号为10位,部门编号为1-3”等特殊知识应用于多行正则表达式,否则@PatrickArtner是正确的。首先,从第一行捕获字段名。然后,从第二行中找出您想要的字段。它不是一个字符串,而是两个不同的字符串。@UnerableLightness“它不是一个字符串”,没问题,您也可以将我的正则表达式应用于单个字符串。它不是一个字符串,而是两个不同的字符串。@UnerableLightness“它不是一个字符串”,没问题,您也可以将我的正则表达式应用于单个字符串。