テキストおよび日常ツール · テキスト ツールキット
^ と $ が 1 回だけ一致する理由: ブラウザーの正規表現フラグによる検索と置換
· 仕組み
正規表現 検索と置換 テキストクリーンアップ
JavaScript 正規表現フラグ (グローバル、複数行、および dotAll) と、複数行アンカー ^ と $ を使用せずに検索と置換ボックスがテキスト全体にコンパイルされる理由と、代わりに機能するパターンについて説明します。
最初の行のみを修正するパターン — ^ が「各行の先頭」を意味すると予想した場合に何が起こるか
貼り付けられたリストには、すべての行に同じ不要なプレフィックスが含まれている可能性がありますが、`^prefix` を検索すると最初の行からのみ削除されます。驚くべき結果は、一貫性のないデータからではなく、パターン構成から得られます。 ToolAcre では、正規表現が複数行モードなしでコンパイルされるため、`^` は完全なテキストの開始を識別します。
一致する `$` アンカーは、もう一方の端でも同じルールに従います。つまり、テキスト内で終わるすべての行ではなく、完全なテキストの終わりを識別します。改行は入力の一部として残りますが、別のアンカー位置にはなりません。クリーンアップされたリストをインポートする前に、報告された置換数を確認してください。カウントが 1 の場合、不一致が直ちに明らかになります。
g フラグ — 「1 つのパスですべての一致を置換」する理由は、設定されているグローバル フラグに依存します
ToolAcre は常にグローバル `g` フラグを使用して検索パターンを構築します。この選択により、JavaScript は最初の一致の後で停止するのではなく、重複しない一致をすべて収集するように指示されます。このツールは、まず `match` を呼び出してカウントを決定し、次に同じグローバル パターンを `replace` に渡します。そのため、表示される数値と置換パスは 1 つの一致ルールを使用します。
グローバル マッチングでは、パターンが認識しない位置を作成できません。 `^prefix` では、適格な全文開始が 1 つだけであるため、`g` は依然として 1 つの一致を見つけます。複数の行で発生する可能性のあるパターンでは、`g` を使用して、すべての行を置き換えることができます。デバッグ時はこれらの質問を分けてください。アンカーは一致を開始する場所を決定し、グローバル モードは検索を続行するかどうかを決定します。
m フラグ — 複数行で ^ と $ が全文アンカーから行アンカーにどのように変更されるか、およびこのツールがそれを省略する理由
複数行の `m` フラグは、`^` および `$` の解釈方法を変更し、行末記号の周囲の位置および外側のテキスト境界を認識できるようにします。 ToolAcre はそのフラグを追加しません。そのコンパイラは、大文字と小文字を区別する検索には `g` を使用し、大文字と小文字の区別がクリアされる場合は `gi` を使用し、追加のフラグをユーザーが制御することはありません。
複数行を使用不可のままにすると、インターフェイスは小さく保たれますが、`gm` で構成されたエディターからコピーされたパターンがここで異なる動作をする可能性があることを意味します。よく知られた表現にフラグが付いているとは考えないでください。 RegExp の作成時に JavaScript フラグ文字が提供され、このツールは別のモードを暗黙的に有効にするのではなく、サポートされていないインライン フラグ構文を拒否します。
s フラグ — ドットがデフォルトで改行に一致しない理由と、ドットを使用せずに複数の行にまたがって一致させる方法
コンパイラは dotAll `s` フラグも省略するため、このツールのドットは改行と一致しません。 `BEGIN.*END` などのパターンは、両方のマーカーが 1 行上にある場合には一致しますが、マーカーが複数の行にまたがる場合は最初の改行で停止します。グローバル モードを追加しても、ドット自体が消費できる内容は変わりません。
行をまたがる一致が本当に必要な場合は、許可される文字を明示的に記述します。 `[\s\S]*?` などのクラスは、消極的なままでも空白と非空白にまたがることができますが、広範なパターンは最初に小さなサンプルでテストする価値があります。コンパイラは無効な構文を検出しますが、重大なバックトラッキング動作を伴う高価な式からタブを保護しません。
改行を明示的に一致させる - 複数行が使用できない場合、パターン内で \n を使用して行の開始と終了をターゲットにします
複数行モードを使用しない繰り返し行の開始の場合は、テキストの先頭または改行のいずれかに一致します: `(^|\n)prefix`。最初の代替案は最初の行を処理し、2 番目の代替案は先行する改行を使用して後の行を処理します。括弧は一致した境界をキャプチャし、置換によって行を分離した構造を保持する方法を提供します。
この手法では、パターン内に改行区切り文字が含まれていることを前提としています。テキスト ライブラリは専用線操作を実行するときに CRLF、LF、および単独の CR を認識しますが、検索と置換は元の文字列を直接検索します。貼り付けたコンテンツが別の行末形式を使用している場合は、最初にそれを正規化するか、意図的に式を調整します。そうしないと、画面上では同一に見えても、後の行は変更されないままになる可能性があります。
(^|\n) を使用して行の境界を明示的に一致させ、キャプチャされた区切り文字を保持します
入力が別々の行にある `ID: apple`、`ID: pear`、および `ID: plum` であるとします。 Regex を有効にし、`(^|\n)ID: ` を見つけて、`$1` に置き換えます。最初の行の `$1` は空の開始位置です。後続の行では、キャプチャされた改行になります。ラベルは消えますが、3 つの行の境界はすべて所定の位置に残ります。
結果を受け入れる前に、置換カウントを読み取ります。この例では、3 行により 3 つの置換が生成されます。カウントが 1 の場合は、操作を繰り返すのではなく、実際のパターンと行末を検査します。置換後に元に戻すことができるため、同じ式が長いインポート リストに影響する前に、小規模なトライアルで一致と再構築の両方を確認できます。
これでカバーされないもの — u、i、y フラグ、および置換への改行の挿入 (単一行フィールドでは実行できない)
この実装では、大文字と小文字の区別がオフになっている場合にも `i` が使用されますが、`u`、`y`、`m`、または `s` のコントロールは公開されません。この記事では、例に必要なマルチライン効果と dotAll 効果が欠けていることを説明するだけで、これらの使用できないモードに動作を割り当てることはしません。別の JavaScript 環境からのパターンは、ToolAcre が実際にコンパイルするフラグに対してレビューする必要があります。
ソースは、置換テキストが JavaScript `String.replace` に渡されることを証明しているため、`$1`、`$&`、`$$` などの置換は JavaScript の意味を保持します。ここで使用されるファイルからレンダリングされたフィールドによって提供されるすべてのインタラクションを確立するわけではありません。特に、インターフェイスを介して物理的な改行を挿入する場合は、アウトラインだけから推測するのではなく、テストする必要があります。
他のフラグと置換フィールドの動作は、このツールの実装の範囲外です。
インターフェイスにパターン本体のみが表示される場合でも、フラグを正規表現の一部として扱います。 ToolAcre では、すべての検索はグローバルであり、オプションの大文字と小文字を区別しないモードでは `i` が追加され、複数行と dotAll は存在しません。これらの事実は、`^`、`$`、およびドットがデフォルトの全文制約と単一行制約を維持しながら、通常の一致では置換が継続される理由を説明しています。
プレフィックス付きの貼り付けリストの場合、`(^|\n)prefix` と `$1` が境界に名前を付けて保持するため、実際的な回避策となります。代表的な行から開始し、カウントを確認し、結果のライン構造を検査してから、完全なデータセットを処理します。この手順により、不可解な 1 試合の結果が、インポート前にレビュー可能なクリーンアップ手順に変わります。