Python 根据特定的正则表达式断言条件提取多行
我有一个大的文本文件,我需要根据下面几行中的特定条件提取某些数据块。如何找到这些块并使用Python正则表达式包提取它们 示例文件(source.txt)如下所示Python 根据特定的正则表达式断言条件提取多行,python,regex,python-3.x,regex-lookarounds,regex-group,Python,Regex,Python 3.x,Regex Lookarounds,Regex Group,我有一个大的文本文件,我需要根据下面几行中的特定条件提取某些数据块。如何找到这些块并使用Python正则表达式包提取它们 示例文件(source.txt)如下所示 . . . Request: 22:11:22 Discription1: From the Client 1 Discription2: requesting HTTP Version: 1.2 Type: browsing Data: AAAA CFFFF F
.
.
.
Request: 22:11:22
Discription1: From the Client 1
Discription2: requesting HTTP
Version: 1.2
Type: browsing
Data: AAAA CFFFF FFF
Answer: 33:22:44
Discription1: From Server B
Discription2: Respons HHTP
Version: 1.1
Type: browsing
Data: kCmkc9AS 9as9 as99 as76d 8aS9d8 6ASDQWv sf
Request: 31:24:53:33
Discription1: From Client 2
Discription2: requesting HTTP
Version: 1.1
Type: DASH
Data: AAAA CFFFF FFF
Answer: 41:24:33:33
Discription1: From Server A
Discription2: Response
Version: 1.1
Type: DASH
Data:ask sef k5q3 WEB 54 fkl n5 qwe@#%@#SDG adkjwra;k4 kfk
Request: 61:44:23:33
Discription1: From Client 2
Discription2: requesting HTTP
Version: 1.1
Type: DASH
Data: AAAA CFFFF FFF
Data Discription: From the Cleint VM2
Answer: 71:25:33:33
Discription1: From Server A
Discription2: Response
Version: 1.1
Type: DASH
Data:ask sef k5q3 WEB 54 fkl n5 qwe@#%@#SDG adkjwra;k4 kfk
.
.
我需要得到以“Request:”开头的块,并带有“version1.1”和“client2”的特性
重要注意事项
预期产出为:
Request: 31:24:53:33
Discription1: From Client 2
Discription2: requesting HTTP
Version: 1.1
Type: DASH
Data: AAAA CFFFF FFF
Request: 61:44:23:33
Discription1: From Client 2
Discription2: requesting HTTP
Version: 1.1
Type: DASH
Data: AAAA CFFFF FFF
Data Discription: From the Cleint VM2
您可以使用负lookaheads在下一行断言值:
^Message Request: .*(?:\r?\n(?!.* Client 2|Data:).*)*\r?\n.*Client 2.*(?:\r?\n(?!Version: 1\.1).*)*\r?\nVersion: 1\.1(?:\n(?!Data:).*)*\r?\nData: .*
解释
行的开头^
匹配消息请求:和行的其余部分消息请求:.*
只要行不包含Client 2或以数据开头,则匹配:(?:\r?\n(?。*Client 2 | Data:).*))*
将该行与客户端2匹配\r?\n.*客户端2.*
只要行不包含版本1.1,就匹配(?:\r?\n(?!Version:1\.1)。*)*
匹配包含版本1.1的行\r?\n版本:1\.1
只要行不以数据开头,就匹配:(?:\n(?!Data:).*))*
匹配以数据开头的行:\r?\n数据:.*
re.M
import re
regex = r"^Message Request: .*(?:\r?\n(?!.* Client 2|Data:).*)*\r?\n.*Client 2.*(?:\r?\n(?!Version: 1\.1).*)*\r?\nVersion: 1\.1(?:\n(?!Data:).*)*\r?\nData: .*"
with open("source.txt", "r") as f:
text1 = f.read()
print (re.findall(regex,text1, re.M))
结果
['Message Request: 31:24:53:33\nDiscription1: From Client 2\nDiscription2: requesting HTTP\nVersion: 1.1\nType: DASH\nData: AAAA CFFFF FFF', 'Message Request: 61:44:23:33\nDescription0:jdfj sdjd\nDiscription1: From Client 2\nDiscription2: requesting HTTP\nVersion: 1.1\nType: DASH\nData: AAAA CFFFF FFF']
你需要比这更清楚。给出一个示例场景。该问题现在已被删除(10k+用户可以看到它,但他们将无法评论或回答)。我已更新了此问题。我是否可以不使用否定断言?这是因为我有很多版本类型。另外,我能不能从一开始就不使用serarch和^,在calse中这不是第一行。如果你能简化这个模式,我会非常感激,因为它非常高级,需要拆分,至少对我这个初学者来说是这样。如果你想的话,你可以省略
^
,但是比赛也可以从另一个地方开始。您在问题中提到了version1.1
,因此我假设应该在模式中指定。负向前看仅确保该行不包含该值。你说的不同类型是什么意思?它们能在哪里发生?我能想到块的结尾是“消息回答:”不是数据吗?这是因为请求块中的字段可能不同,但唯一稳定的字段是条件。例如,假设您有其他版本,例如1.2、1.0