10/14 に投稿したJavascript で diff (通信なし、ローカルで完結)の内部仕様についての補足、その2です。
補足その1はこちらです。 Javascript で diff (内部仕様についての補足)
diff の出力結果をクリーンナップしてみる
「空行を含む関数を別の(空行を含んだ)関数に差し替える」ような場合、「関数1に含まれる空行」と「関数2に含まれる空行」群が一致行とみなされて、まだら模様の差分が生成されることがあります。
diff_orzでは、「前後の行ごと一致しなければ空行どうしのマッチングを認めない」というルールで、まだら模様の差分が生成されるのを回避しています。
同様に、単語単位の差分でも、「単語の間にはさまった空白は、前後のフレーズごと一致しなければマッチングを認めない」というルールを設けるようにします。
単語単位の差分の境界を調整する
- 文字列1 「<tr><td>1</td></tr>」
- 文字列2 「<tr><td>1</td><td>2</td></tr>」
上記のような例題に対して、数学的な手段のみで差分を取ると「td>2<」「td></」が差分として検出されますが、意味的には「<td>2</td>」を差分として検出させたいわけです。
構文解析を行って「<tr>」「<td>」「1」……を単語として検出すれば完璧ですが、今回は「(<{[など左かっこを特別扱い」「</」は単一の単語として扱う」というルールを設け、一旦普通に差分をとった後、左かっこの位置まで差分の境界位置をずらしています。