文字列の replace 時に途中のマッチは無視して最後の文字にマッチしてしまう

カテゴリ:JavaScript

以下のようなコードで、pre 要素内の文字を置換したいとします。
function replacePre(text) {
    const originalString = text;
    const pattern = /(<pre>)(.*)(<\/pre>)/gs;
    const newString = originalString.replaceAll(pattern, "$1Matched!$3");

    return newString;
}

str = "<pre>Test</pre><pre>Test</pre><pre>Test</pre>"
console.log(replacePre(str));

しかし実行した結果は以下となり、3つあった pre 要素が 1 つだけになってしまっています。

実行結果)

$ node replacepre.js 
<pre>Matched!</pre>

原因はアスタリスク(*)の貪欲マッチで、途中の pre 閉じタグは無視して、最後の pre 閉じタグにマッチしてしまっているのです。当然これは開発者の意図するところではありません。

貪欲マッチを避けるためには * の後ろに ? を付けます。これを最短マッチと呼びます。最初にマッチした時点で置換処理を実施、置換後再び検索、という処理を繰り返し実施します。

function replacePre(text) {
    const originalString = text;
    const pattern = /(<pre>)(.*?)(<\/pre>)/gs;
    const newString = originalString.replaceAll(pattern, "$1Matched!$3");

    return newString;
}

str = "<pre>Test</pre><pre>Test</pre><pre>Test</pre>"
console.log(replacePre(str));

実行結果)

$ node replacepre.js 
<pre>Matched!</pre><pre>Matched!</pre><pre>Matched!</pre>

公開日時:2025年05月05日 14:00:18
最終更新日時:2025年05月05日 14:16:59

なお、レンタルサーバー選びで迷ったらこちらの記事で主要レンタルサーバーのプランと料金を比較していますので、是非参考にしてみてください。

JavaScriptに戻る

このページのトップに戻る