これは何ですか?私は 'dd'が何であるか分からず、ヘッダーとフッターは特定の方法で始まる1行であると思っています。ユースケースに合わせてヘッダーとフッターに一致するロジックを置き換える必要があります。
import re
VALID_DOCUMENT_A = \
"""
header: 1
Hi there.
This is the body of page 1.
footer: 1
header: 2
This is the second page.
footer: 2
"""
VALID_DOCUMENT_B = \
"""
header: 1
Hi there.
This is the body of page 1.
footer: 1
header: 2
This is the second page.
footer: 2
header: 3
This third page has a header but no footer.
"""
INVALID_DOCUMENT_A = \
"""
header: 1
Hi there.
This is the body of page 1.
footer: 1
This is the second page. Where's the header, though?
footer: 2
"""
INVALID_DOCUMENT_B = \
"""
header: 1
Hi there.
This is the body of page 1.
footer: 1a
footer: 1b
This is the second page. Oops - two footers above.
footer: 2
"""
INVALID_DOCUMENT_C = \
"""
header: 1
Hi there.
This is the body of page 1.
footer: 1
header: 2a
header: 2b
This is the second page. Oops - two headers above.
footer: 2
"""
def is_header(line):
return re.match('^header:.*', line)
def is_footer(line):
return re.match('^footer:.*', line)
def pair_headers_and_footers(text):
lines = text.splitlines()
stack = []
for i, line in enumerate(lines, 1):
if is_header(line):
if stack:
raise ValueError('Got unexpected header on line {}'.format(i))
stack.append(line)
elif is_footer(line):
if not stack:
raise ValueError('Got unexpected footer on line {}'.format(i))
yield stack.pop(), line
if __name__ == '__main__':
documents = [
VALID_DOCUMENT_A, # 2 headers, 2 footers
VALID_DOCUMENT_B, # 3 headers, 2 footers
INVALID_DOCUMENT_A, # missing header for page 1
INVALID_DOCUMENT_B, # multiple footers for page 1
INVALID_DOCUMENT_C # multiple headers for page 2
]
for document in documents:
try:
print(list(pair_headers_and_footers(document)))
except ValueError as e:
print(e)
出力
[('header: 1', 'footer: 1'), ('header: 2', 'footer: 2')]
[('header: 1', 'footer: 1'), ('header: 2', 'footer: 2')]
Got unexpected footer on line 7
Got unexpected footer on line 6
Got unexpected header on line 7
補遺
私は機能pair_headers_and_footers
に、あなたは置き換えることができることを追加する必要があります:
lines = text.splitlines()
をして:
lines = (m.group(0).rstrip() for m in re.finditer('(.*\n|.+$)', text))
これは、特に大量のテキストを処理している場合など、メモリ使用量を減らすのに役立ちます。この変更により、ヘッダーとフッターのペアリングのプロセス全体が「怠け者」になります。
括弧が私に似ています。最も簡単な解決策の1つは、スタックを使用することです。https://interactivepython.org/runestone/static/pythonds/BasicDS/SimpleBalancedParentheses.html –
したがって、見つかったすべてのヘッダーに最初に使用されていない(マップされていない)フッタが見つかるようにしますヘッダーの後ろに右? –