如何提取两个不同匹配之间的文本?

1 投票
2 回答
1562 浏览
提问于 2025-04-16 00:18

我有一个文本文件,里面有一些我需要提取的文本,格式大概是这样的:

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,来找到我想要的文本位置。但是我需要做很多次,所以我需要的是:

  1. 从 ITEM A 开始写,直到 ITEM B 停止。
  2. 如果第一次提取的文本少于 50 个字符,就丢掉,继续下一个。
  3. 一旦找到一个以 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模块中提供的标志。

撰写回答