由于背景解释起来很复杂,我正在编写伪代码, 我只对 Python-Regex-Pattern 感兴趣,希望你们能帮帮我
我有以下输入文本(很多行以 \n
作为行分隔符浓缩为“.”):
.
.
1 Order
order1 stuff
order1 stuff
etc
ShippingMethod: Truck
.
.
2 Order
order2 stuff
order2 stuff
etc
ShippingMethod: Truck
.
.
Order Summary
.
.
我只想匹配“订单”和“卡车”之间的文本对于每个订单,然后我将在程序中进一步迭代结果。
我的正则表达式:(为了更好的可读性,我将其拆分为“开始、内容、结束”)。
pattern = \d\s*Order + [.|\s|\S]* + Truck
当我执行这场比赛时,我得到一个结果,从 1 Order
开始并在 second Truck
处停止:
1 Order
order1 stuff
order1 stuff
etc
ShippingMethod: Truck
.
.
2 Order
order2 stuff
order2 stuff
etc
ShippingMethod: Truck
我想要(在这种情况下)正好两个匹配,其中只包含一个订单的内容:
1 Order
order1 stuff
order1 stuff
etc
ShippingMethod: Truck
2 Order
order2 stuff
order2 stuff
etc
ShippingMethod: Truck
我希望很清楚我在寻找什么。非常感谢任何帮助。
提前感谢,保持安全,保持健康!
您可能建议的事项:
答案 0 :(得分:0)
解决方案看似简单 - 使用非贪婪运算符 ?
。
首先,字符类正则表达式 []
匹配其中的任何字符,因此要匹配 a
和 b
,正则表达式是 [ab]
而不是 {{1} }.所以代码的 content 部分应该是 [a|b]
。
另外,[.\s\S]
和 \s
分别匹配所有空格和非空格,所以句号 (\S
) 在这里无关紧要。
所以最终的内容部分应该是这样的:.
在任何正常频率运算符(如 [\s\S]*
、?
和 +
)之后的贪婪 *
运算符告诉正则表达式匹配 尽可能少的元素可能。使用 ?
,您将使用 零个或多个 的默认贪婪版本,告诉正则表达式匹配尽可能多的(最终匹配第一个 {{1} } 你想要!)
所以我们在最后添加了一个非贪婪运算符,所以最终的正则表达式如下所示:
*
字符类 Truck
是告诉正则表达式匹配每个字符的巧妙方法(因为每个字符要么是空格要么不是空格)。但事实证明,有一种方法可以通过使用 \d\s*Order[\s\S]*?Truck
修饰符来提高效率。它做它所说的 - 它告诉正则表达式 [\s\S]
(DOT)应该匹配所有字符,包括换行符。
如果这是您使用的代码:
re.DOTALL
这是最好的代码(包括问题的解决方案):
.
如您所见,re.findall(r'\d\s*Order[\s\S]*?Truck', input_text)
现在将匹配从 re.findall(r'\d\s*Order.*?Truck', input_text, re.DOTALL)
到 .*?
的所有内容(包括换行符)。
答案 1 :(得分:0)
不使用 re.DOTALL,如果 Truck
不存在,则防止过度匹配,您可以使用:
^\d+\s*Order\b.*(?:\n(?!\d+\s* Order\b|.* Truck$).*)*\n.* Truck$
模式匹配:
^
字符串开头\d+\s*Order\b.*
匹配数字后跟 Order
和行的其余部分(?:
非捕获组
\n(?!\d+\s* Order\b|.* Truck$)
匹配换行符并断言该行不以数字和 Order
开头并断言该行不以 Truck
结尾.*
如果断言为真,则匹配整行)*
关闭非捕获组以匹配所有行\n.* Truck$
匹配换行符和以 Truck
结尾的行的其余部分import re
regex = r"^\d+\s*Order\b.*(?:\n(?!\d+\s* Order\b|.* Truck$).*)*\n.* Truck$"
s = ("\n\n"
"1 Order \n"
"order1 stuff\n"
"order1 stuff\n"
"etc\n"
"ShippingMethod: Truck\n\n\n"
"2 Order\n"
"order2 stuff\n"
"order2 stuff\n"
"etc\n"
"ShippingMethod: Truck\n\n\n"
"Order Summary\n\n")
print(re.findall(regex, s, re.MULTILINE))
输出
['1 Order \norder1 stuff\norder1 stuff\netc\nShippingMethod: Truck', '2 Order\norder2 stuff\norder2 stuff\netc\nShippingMethod: Truck']