如何提取两个不同匹配之间的文本?
我有一个文本文件,里面有一些我需要提取的文本,格式大概是这样的:
ITEM A blah blah blah ITEM B bloo bloo bloo ITEM A blee blee blee ITEM B
这是我目前写的可用代码:
finda = r'(Item\sA)'
findb = r'(Item\sB)'
match_a = re.finditer(finda, usefile, 2) # the "2" is a flag to say ignore case
match_b = re.finditer(findb, usefile, 2)
我知道可以用一些命令,比如 span、start 和 end,来找到我想要的文本位置。但是我需要做很多次,所以我需要的是:
- 从 ITEM A 开始写,直到 ITEM B 停止。
- 如果第一次提取的文本少于 50 个字符,就丢掉,继续下一个。
- 一旦找到一个以 ITEM A 开头、以 ITEM B 结尾并且长度超过 50 个字符的文本,就把它写入文件。
非常感谢!我已经纠结了一段时间了。
2 个回答
2
这可以通过一个正则表达式来完成:
with open("output.txt", "w") as f:
for match in re.finditer(r"(?<=Item\sA)(?:(?!Item\sB).){50,}(?=Item\sB)", subject, re.I):
f.write(match.group()+"\n")
这个表达式会匹配“项目A”和“项目B”之间的内容。或者你是想同时匹配分隔符呢?
下面是对这个正则表达式的解释:
(?<=Item\sA) # assert that we start our match right after "Item A"
(?: # start repeated group (non-capturing)
(?!Item\sB) # assert that we're not running into "Item B"
. # then match any character
){50,} # repeat this at least 50 times
(?=Item\sB) # then assert that "Item B" follows next (without making it part of the match)
2
为什么不直接这样做:
with open(fname, 'w') as file:
for match in re.finditer(r'Item A(.+?)Item B', subject, re.I):
s = match.group(1)
if len(s) > 50:
file.write(s)
注意:直接使用标志的实际数值会让人感到困惑,建议使用re
模块中提供的标志。