🔎

pythonのSequenceMatcherでdiffコマンドっぽい出力をする

2021/10/26に公開約1,100字

pythonのdifflibを使っていて、コンテキスト表記が今ひとつしっくりこなかったので、diffっぽく表示するスクリプトを書きました。

from difflib import SequenceMatcher

a = "qqabxxcdf"  # サンプル文字列1
b = "abyycdfgh"  # サンプル文字列2
s = SequenceMatcher(None, a, b)

for tag, i1, i2, j1, j2 in s.get_opcodes():

    # 公式ドキュメントによるとこれ以外が来ることはないが一応確認
    assert tag in ["equal", "replace", "delete", "insert"]

    i_row_str = f"{i1 + 1},{i2}" if i1 != i2 - 1 else f"{i1 + 1}"
    j_row_str = f"{j1 + 1},{j2}" if j1 != j2 - 1 else f"{j1 + 1}"

    if tag == "equal":
        continue

    if tag == "replace":
        print(f"{i_row_str}c{j_row_str}")
        for i in range(i1, i2):
            print("<", a[i])
        print("---")
        for j in range(j1, j2):
            print(">", b[j])
    elif tag == "delete":
        j_row_str = f"{j1}"
        print(f"{i_row_str}d{j_row_str}")
        for i in range(i1, i2):
            print("<", a[i])
    elif tag == "insert":
        i_row_str = f"{i1}"
        print(f"{i_row_str}a{j_row_str}")
        for j in range(j1, j2):
            print(">", b[j])

出力

1,2d0
< q
< q
5,6c3,4
< x
< x
---
> y
> y
9a8,9
> g
> h

参考

https://docs.python.org/ja/3/library/difflib.html#module-difflib

Discussion

ログインするとコメントできます