Skip to content

建立 2026-09-15 更新 2026-09-15

日誌與多行文字

日誌一行一筆時,用 re.M^ 對齊行首。訊息跨很多行時,用 re.S. 吃換行,或明確寫 \n

抽出 ERROR 行

import re

log = """
2026-09-15 10:01:02 INFO started
2026-09-15 10:01:03 ERROR disk full
2026-09-15 10:01:04 INFO retry
2026-09-15 10:01:05 ERROR timeout
"""

LINE = re.compile(
    r"^(?P<ts>\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (?P<level>ERROR) (?P<msg>.*)$",
    re.MULTILINE,
)

for m in LINE.finditer(log):
    print(m["ts"], m["msg"])

簡易 combined log(Nginx / Apache 常見形狀)

import re

line = (
    '203.0.113.10 - - [15/Sep/2026:10:19:00 +0800] '
    '"GET /regex HTTP/1.1" 200 1234'
)

ACCESS = re.compile(
    r"""
    ^(?P<ip>\S+)
    \s+\S+\s+\S+\s+
    \[(?P<time>[^\]]+)\]
    \s+"(?P<method>\S+)\s+(?P<path>\S+)\s+(?P<proto>[^"]+)"
    \s+(?P<status>\d{3})
    \s+(?P<size>\S+)
    """,
    re.VERBOSE,
)

m = ACCESS.search(line)
print(m.groupdict() if m else "parse failed")

正式環境用專門的 log parser 或先 split 再對時間戳用一小段 regex。這條示範「空白分欄 + 方括號時間 + 引號請求列」。

跨行區塊

import re

trace = """
TRACE begin
detail line 1
detail line 2
TRACE end
noise
"""

block = re.search(
    r"TRACE begin.*?TRACE end",
    trace,
    flags=re.DOTALL,
)
print(block.group(0) if block else None)

沒有 re.S 時,. 遇換行就停,beginend 不在同一行就匹配不到。.*? 懶惰,避免一次吃到檔案最後一個 TRACE end

切段落

import re

doc = "第一段。\n\n第二段還有內容。\n\n\n第三段。"
parts = [p.strip() for p in re.split(r"\n\s*\n", doc) if p.strip()]
print(parts)

相關資料