入力とファイル読込
テキスト差分抽出ツールの基本機能として,比較元(Original)と比較先(Modified)の2つの独立したテキスト入力フィールドを備えています.直接入力やクリップボードからの貼り付け操作のほか,ローカルに保存されたファイルの読み込み機能を利用して,既存のドキュメントのテキスト内容を素早くシステムに反映させることができます.
システムの安定した動作を確保するため,入力対象となる文字列データには上限が設けられており,比較元と比較先のそれぞれについて最大20,000 UTF-16コード単位までに制限されています.直接手入力や貼り付けを行うテキストエリア(textarea)にはmaxLength属性が設定されているため,この上限を超える文字入力自体がブラウザの機能によってシステム的に制限されます.
一方で,ファイルアップロード機能を利用して外部からデータを読み込む場合,対象のファイルサイズ上限は1MiBに設定されています.指定されたファイルから抽出されたテキストが前述の20,000コード単位の制限を超過した場合に限り,超過を知らせる警告メッセージがインターフェース上に表示され,該当ファイルの読み込み処理が中断される仕組みとなっています.
内部的な処理メカニズムとしては,ブラウザが提供するFileReader APIのreadAsTextメソッドを用いて対象ファイルを非同期に読み込みますが,システムは入力されたバイトデータを自動的にUTF-8形式のテキストファイルとして解釈します.そのため,Shift-JISやEUC-JPなどの異なる文字エンコーディングで保存されたファイルを指定した場合は,文字化けが発生する可能性が高くなります.
この一連のファイルの読み込みおよびテキスト展開の動作は,すべてクライアントサイドのブラウザ環境内でのみ完結しています.入力されたテキストデータをローカルのメモリ上に展開して処理を行うため,インターネットを通じて外部のサーバーへデータが送信されたり,アップロードされたりする処理は一切含まれていません.
また,入力フィールドが空の場合であっても,システムは例外エラーをスローすることなく正常に処理を実行し続けます.後述する一致度の計算処理においても,空文字列同士の比較は「変更が存在しない同一の状態である」と解釈され,そのまま後続の処理が継続されるよう設計されています.
行・単語・文字
差分の比較プロセスは,利用者が意図する確認の粒度に応じて「行単位」「単語単位」「文字単位」という3つの異なるモードから選択して実行することができます.行単位の比較モードでは,テキスト内に含まれるCRLF,CR,またはLFの各改行コードを区切り文字として扱い,全体のテキストを配列に分割します.
この際,分割されて配列化された各行の文字列が1つの独立した項目として評価の対象となります.単語単位の比較モードにおいては,高度な自然言語処理や辞書を用いた形態素解析による意味的な文脈分割は一切行われないという点に注意が必要です.具体的な実装としては,英数字やアンダースコアの連続する塊,空白文字の連続,あるいはそれ以外の1文字を正規表現パターン(\s+|[A-Za-z0-9_]+|[^\s]など)に対してuフラグ(Unicodeモード)を用いて順番にトークン化していきます.
この仕様により,日本語のテキストに対して単語単位の比較を適用した場合,英語のような空白区切りによる単語抽出とは全く異なる挙動を示します.日本語の漢字,ひらがな,カタカナなどは単語の塊として認識されることはなく,概ね1Unicodeコードポイントずつ,つまり1文字単位の項目として分割して扱われることになります.
また,複数のコードポイントから構成される絵文字の結合列などについても,全体が常に1つの項目としてまとまって扱われるとは限りません.文字単位の比較モードでは,内部的にArray.from()メソッドなどを適用して,テキスト全体をより厳格に1文字(1コードポイント)ずつの配列に分解します.
比較の基礎的なロジックとして稼働するのは,ユージン・マイヤーズ(Eugene W. Myers)の差分抽出アルゴリズムに基づいた処理であり,前述のルールによって構築された各トークン配列同士を比較し,最も効率的な追加と削除の経路を計算します.これにより,変更箇所だけを視覚的なハイライトとして反映させる仕組みとなっています.
単語モードや文字モードを利用する際は,言語ごとの特殊な文字結合ルールや正規表現の特性によって,必ずしも人間が直感的に認識する「1文字」や「1単語」と完全に一致する境界で差分が検出されるわけではないことを理解した上で活用する必要があります.
余白と大小文字
テキスト比較を行う際,前後の不揃いな余白の有無や,アルファベットの大文字・小文字の違いを意図的に無視し,文字列の論理的な差異のみに焦点を当てるためのオプション設定が用意されています.「前後の余白を無視」というオプションを有効にした場合,比較アルゴリズムに渡される前の各項目の文字列に対してtrim()メソッドが適用され,文字列の先頭および末尾に存在する空白文字が取り除かれます.
さらに,項目の文字列の内部に含まれる連続したスペースやタブなどの空白群は,単一の半角スペースに統合されるという前処理が行われます.ここで注意が必要なのは,これらの空白に対する処理(trimと空白の統合)は,テキスト全体に対して一律に行われるのではなく,選択されたモード(行・単語・文字)に従って分割された「各項目」に対して個別に適用されるという点です.
したがって,元のテキストに存在する任意の内部の空白差や,ソースコードなどに見られるインデントの深さの違いが,このオプションによって常に完全に無視されるという保証はありません.分割の粒度や空白の位置によっては,空白の差異が依然として変更箇所として検出されるケースが存在します.
一方,「大文字・小文字を無視」するオプションを有効にした場合,比較判定の内部処理においてのみ,配列化された文字列がtoLowerCase()メソッドによって一時的に小文字へと変換され,大文字と小文字の差異がないものとして比較計算が実行されます.ただし,Unicodeの小文字拡張処理に対する対応には項目ごとに制限が含まれる場合があるため,特殊な言語の文字などでは意図した通りに同一視されない可能性があります.
この機能において重要な実装仕様は,文字列の小文字化処理が適用されるのが内部的な一致判定の計算を行う瞬間に限定されているという事実です.最終的に画面へレンダリングされてユーザーに提示される差分結果のテキストには,利用者が入力フィールドに入力したオリジナルの文字の大小関係がそのまま維持されて出力されます.
これにより,元のドキュメントのフォーマットや表記を視覚的に損なうことなく,変更箇所を確認することが可能となっています.
追加削除と一致度
抽出されたテキストの差分結果は,追加項目数,削除項目数,および全体の一致度を示すパーセンテージとして数値化され,インターフェース上のステータスパネルにリアルタイムで表示されます.ここで表示される「一致度」という指標は,文章の意味的な類似度や文脈の近さを示すものではありません.
純粋に,前述の分割ルールによって生成されたトークンの「項目数比率」に基づいた算術的な計算結果を表しています.具体的な計算式としては,まず比較元と比較先の配列間で完全に一致したと判定された項目の数を分子として取得します.そして,一致項目数,追加項目数,削除項目数の3つの数値をすべて合算した合計値を分母として使用します.
この計算によって導き出された割合を,小数点以下で丸めた整数値としてパーセンテージ表示しています.例えば,全く同一の文字列で構成された2つの行を比較した場合,一致項目数が2,追加された項目および削除された項目が0となるため,計算結果の一致度は100%となります.
一方のテキスト入力エリアだけに入力があり他方が空である場合や,すべての文字列が全く異なる内容に書き換えられている状態では,一致項目が0となるため,表示される一致度は0%を示します.また,比較元と比較先の入力フィールドが両方とも空文字である場合は,変更が一切存在しない状態であるという判定に基づき,例外的に一致度は100%として扱われます.
実際の視覚的な表現においては,削除された項目,すなわち比較元には存在していたが比較先には存在しない項目が,赤色の背景色でハイライトされ,要素の先頭には視覚的な補助としてマイナス(-)記号とともに表示されます.これとは逆に追加された項目,すなわち比較先で新たに挿入された項目は,緑色の背景色でハイライトされ,プラス(+)記号が付与されます.
これらの差異が認められず一致していると判定された項目については,特別な背景色や記号は追加されず,通常の標準的なテキストカラーでそのまま表示される設計となっています.
分割・統合とコピー
差分の表示形式については,ユーザーの好みに応じて「2分割表示(Split)」モードと「統合表示(Unified)」モードの2つのレイアウトをタブインターフェースでシームレスに切り替えて確認することができます.2分割表示モードを選択した状態では,画面の左側に比較元のテキスト(Original)が,右側に比較先のテキスト(Modified)が,それぞれ独立したカラムに分けて配置されます.
このモードにおいて,比較元のビュー領域では削除された項目が赤くハイライトされ,比較先のビュー領域では追加された項目が緑色でハイライトされます.行単位の比較モードを利用している際など,削除された直後に新しい行が追加されたような変更箇所については,左右のカラムに並べて視覚的な対比がスムーズに行えるよう,相手側のカラムに適切な空白行が挿入され,垂直方向の行位置合わせが試みられます.
ただし,左右のビュー領域のスクロール位置を自動的に同期して追従させるような機能は現在のところ実装されていないため,長文の差分を確認する際には,ユーザー自身が左右のビューを個別にスクロールして該当箇所を探す必要があります.統合表示モードでは,変更履歴を1つの連続したテキストストリームとして結合して表示します.
削除された赤い行と追加された緑の行が垂直方向に隣接して配置されるため,ソフトウェア開発のコードレビューなどで一般的に見慣れた変更リストに似た形式で差分を確認することができます.さらに,ツールには抽出された差分結果をクリップボードに取得するための「差分をコピー」ボタンが用意されています.
このコピーボタンはヘッダー部分に配置されており,統合表示モード専用ではなく,2分割表示モードであっても統合表示モードであっても,どちらの表示モードを選択している状態からでも利用することが可能です.このボタンを使用すると,追加された行の先頭には「+ 」,削除された行の先頭には「- 」,変更のない行には空白2つ「 」が付与された状態のプレーンテキストとしてデータがクリップボードに保存されます.
出力形式は一般的な差分テキストとして汎用的に利用可能ですが,Gitなどで用いられる標準的なpatchフォーマットの仕様と完全に同一なわけではありません.
探索上限と確認手順
本ツールの差分抽出で採用されているMyersのアルゴリズムは,変更箇所が複雑に交錯するデータや極めて長いテキストに対して,計算処理のワークロードが急激に増加するという特性を持っています.処理が過大になることを抑えるため,内部の探索処理には打ち切りとなる上限値が設定されています.
具体的には,編集の深さの探索を行い,その深さが500以内で差分経路が見つかれば成功として結果を出力します.しかし,探索の深さが500を超える場合,あるいは内部ループにおける作業回数が2,000,000回などの作業上限に到達した場合には,探索処理はフォールバックモードへと移行します.
このリソースの上限に到達した場合,ツールは比較元のテキスト要素をすべて「削除」されたものとし,比較先のテキスト要素をすべて「追加」されたものとして単純に結合した結果を画面に出力します.フォールバックが発生した際には,UIの入力エリア直下にオレンジ色で探索上限に達した旨の警告メッセージが表示されます.
この状態では,変更箇所の細かい特定が行われていないため,算出される一致度も実際の変更割合を反映したものではなくなります.探索上限の超過を回避するための確認手順として,まずは入力データのサイズや比較範囲をより小さく分割してから再度ツールにかけることが推奨されます.
また,「大文字・小文字を無視」や「前後の余白を無視」のオプションを有効にすることで,アルゴリズムから見た不要な差異を減らすことができ,作業回数の上限到達を未然に回避できる場合があります.ブラウザの動作環境への負荷を考慮して設定されたこれらの上限値やフォールバックの仕様を把握しながら利用することで,スムーズなテキスト比較のワークフローを実現することが可能です.