用正则表达式捕获文本块

2024-04-18 06:51:34 发布

您现在位置:Python中文网/ 问答频道 /正文

我有以下格式的结构化文档:

123456789|XXX|1234567|05/05/2012 00:00|81900153|Signed|LASTNAME,FIRSTNAME, M.S.|024813|XXX|3410080|DNR Order Verification:Scanned|

xyz pqs 123

[report_end]

123456789|XXX|1234567|05/05/2012 00:00|81900153|Signed|LASTNAME,FIRSTNAME, M.S.|024813|XXX|3410080|A Note|

xyz pqs 123

[report_end]

其中每个记录:

  • 以以|分隔的11字段行开始
  • 中间有一块自由文本
  • 以标记“[report\u end]”结束

如何用正则表达式捕获这三个元素?你知道吗

我的方法是

  1. 搜索每行有11个字符
  2. 搜索每行有[report_end]
  3. 搜索这两条线之间的任何东西。你知道吗

但我不知道如何用正则表达式来实现这一点。你知道吗


Tags: 文档report格式orderfirstnamexxxendverification
2条回答

您可以使用以下方法:

r"((?:.*?\|){11}\s+(?:.*)\s+\[report_end\])"

输出:

Match 1.    [0-157] `123456789|XXX|1234567|05/05/2012 00:00|81900153|Signed|LASTNAME,FIRSTNAME, M.S.|024813|XXX|3410080|DNR Order Verification:Scanned|

xyz pqs 123

[report_end]


Match 2.    [159-292]   `123456789|XXX|1234567|05/05/2012 00:00|81900153|Signed|LASTNAME,FIRSTNAME, M.S.|024813|XXX|3410080|A Note|

xyz pqs 123

[report_end]

演示

https://regex101.com/r/xY5nI9/1


正则表达式解释

((?:.*?\|){11}\s+(?:.*)\s+\[report_end\])

Options: Case sensitive; Exact spacing; Dot doesn’t match line breaks; ^$ don’t match at line breaks; Regex syntax only

Match the regex below and capture its match into backreference number 1 «((?:.*?\|){11}\s+(?:.*)\s+\[report_end\])»
   Match the regular expression below «(?:.*?\|){11}»
      Exactly 11 times «{11}»
      Match any single character that is NOT a line break character «.*?»
         Between zero and unlimited times, as few times as possible, expanding as needed (lazy) «*?»
      Match the character “|” literally «\|»
   Match a single character that is a “whitespace character” «\s+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
   Match the regular expression below «(?:.*)»
      Match any single character that is NOT a line break character «.*»
         Between zero and unlimited times, as many times as possible, giving back as needed (greedy) «*»
   Match a single character that is a “whitespace character” «\s+»
      Between one and unlimited times, as many times as possible, giving back as needed (greedy) «+»
   Match the character “[” literally «\[»
   Match the character string “report_end” literally «report_end»
   Match the character “]” literally «\]»

根据您的评论更新

要获得3个组,您可以使用:

r"((?:.*?\|){11})\s+(.*)\s+(\[report_end\])

要循环所有组:

import re
pattern = re.compile(r"((?:.*?\|){11})\s+(.*)\s+(\[report_end\])")

for (match1, match2, match3) in re.findall(pattern, string):
    print match1 +"\n"+ match2 +"\n"+ match3 +"\n"

现场演示

http://ideone.com/k8sA3k

您还可以尝试:

^(?P<fields>(?:[^|]+\|){11})(?P<text>[\s\S]+?)(?P<end>\[report_end\])

DEMO

相关问题 更多 >