文字列のすべての出現を置き換える方法は?

2009年07月18日に質問されました。  ·  閲覧回数 3.6M回  ·  ソース

Click Upvote picture
2009年07月18日

私はこの文字列を持っています:

"Test abc test test abc test test test abc test test abc"

行うこと:

str = str.replace('abc', '');

上記の文字列で最初に出現したabcのみを削除するようです。

どうすればそれのすべての発生を置き換えることができますか?

回答

Sean Bright picture
2009年07月18日
4558

2020年8月の時点で、グリーンフィールドブラウザーは、ECMAScript 2021言語仕様で定義されているString.replaceAll()メソッドをサポートしています。 古い/レガシーブラウザのサポートについては、以下が引き続き適用されます。


str = str.replace(/abc/g, '');

コメントへの返信:

var find = 'abc';
var re = new RegExp(find, 'g');

str = str.replace(re, '');

Click Upvoteのコメントに応えて、さらに単純化することができます。

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(find, 'g'), replace);
}

注:正規表現には特殊な(メタ)文字が含まれているため、上記のfind関数で引数を前処理せずに盲目的に渡して、それらの文字をエスケープすることは危険です。 これについては、 Mozilla Developer Network正規表現に関するJavaScriptガイドで説明されています。ここでは、次のユーティリティ関数が示されています(この回答が最初に作成されてから少なくとも2回変更されているため、MDNサイトで更新の可能性を確認してください)。

function escapeRegExp(string) {
  return string.replace(/[.*+\-?^${}()|[\]\\]/g, '\\$&'); // $& means the whole matched string
}

したがって、上記のreplaceAll()関数をより安全にするために、 escapeRegExpも含めると、次のように変更できます。

function replaceAll(str, find, replace) {
  return str.replace(new RegExp(escapeRegExp(find), 'g'), replace);
}
Cory Gross picture
2013年07月12日
2452

完全を期すために、これを行うためにどの方法を使用すべきかを考えるようになりました。 このページの他の回答で示唆されているように、これを行うには基本的に2つの方法があります。

注:一般に、JavaScriptで組み込みのプロトタイプを拡張することは一般的に推奨されていません。 単に説明のためにStringプロトタイプの拡張機能として提供し、 String組み込みプロトタイプでの架空の標準メソッドのさまざまな実装を示しています。


正規表現ベースの実装

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.replace(new RegExp(search, 'g'), replacement);
};

分割と結合(機能)の実装

String.prototype.replaceAll = function(search, replacement) {
    var target = this;
    return target.split(search).join(replacement);
};

正規表現が舞台裏でどのように機能するかを効率的にあまり知らなかったので、以前はパフォーマンスを考えずに分割して実装に参加する傾向がありました。 どちらがより効率的で、どの程度のマージンがあるのか​​疑問に思ったとき、私はそれを言い訳として使用しました。

私のChromeWindows 8マシンでは、正規表現ベースの実装が最速であり、分割と結合の実装は53%遅くなっています。 つまり、正規表現は、私が使用したloremipsum入力の2倍の速度です。

これら2つの実装を相互に実行しているこのベンチマークを確認してください。


@ThomasLeducなどによる以下のコメントに記載されているように、 searchに正規表現で特殊文字として予約されている特定の文字が含まれている場合、正規表現ベースの実装で問題が発生する可能性があり正規表現(MDN)のテーブルに文字がない文字列のみを渡すことを前提としています。

MDNは、文字列をエスケープするための実装も提供します。 これもRegExp.escape(str)として標準化されていればいいのですが、残念ながら、存在しません。

function escapeRegExp(str) {
  return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string
}

String.prototype.replaceAll実装内でescapeRegExp呼び出すこともできますが、これがパフォーマンスにどの程度影響するかはわかりません(すべての英数字文字列のように、エスケープが不要な文字列の場合でも可能性があります) )。

Matthew Crumley picture
2009年07月18日
1879

更新: 2020年8月の時点で、次のようにreplaceAllを使用できます。

let result = "1 abc 2 abc 3".replaceAll("abc", "xyz");
// `result` is "1 xyz 2 xyz 3"

古いブラウザの場合:

注:パフォーマンスが重要なコードでは、次のソリューションを使用しないでください。

単純なリテラル文字列の正規表現の代わりに、次を使用できます。

str = "Test abc test test abc test...".split("abc").join("");

一般的なパターンは

str.split(search).join(replacement)

これは、 replaceAllと正規表現を使用するよりも高速である場合がありましたが、最近のブラウザーではそうではないようです。

ベンチマーク: https

結論:パフォーマンスが重要なユースケース(数百の文字列の処理など)がある場合は、Regexpメソッドを使用します。 しかし、ほとんどの典型的なユースケースでは、これは特殊文字について心配する必要がない価値があります。

Adam A picture
2009年05月07日
718

gフラグが設定された正規表現を使用すると、すべてが置き換えられます。

someString = 'the cat looks like a cat';
anotherString = someString.replace(/cat/g, 'dog');
// anotherString now contains "the dog looks like a dog"

こちらもご覧ください

jesal picture
2013年02月12日
114

受け入れられた回答に基づく文字列プロトタイプ関数は次のとおりです。

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find, 'g'), replace);
};

編集

findに特殊文字が含まれる場合は、それらをエスケープする必要があります。

String.prototype.replaceAll = function (find, replace) {
    var str = this;
    return str.replace(new RegExp(find.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'), 'g'), replace);
};

フィドル: http

Elias Van Ootegem picture
2012年03月01日
88

更新:

更新には少し遅れていますが、この質問に出くわしたばかりで、以前の回答が満足のいくものではないことに気づきました。 質問には1つの単語の置き換えが含まれていたため、単語の境界を使用することを誰も考えていなかったとは信じられません( \b

'a cat is not a caterpillar'.replace(/\bcat\b/gi,'dog');
//"a dog is not a caterpillar"

これは、ほとんどの場合、単語の一部を置き換えることを回避する単純な正規表現です。 ただし、ダッシュ-は依然として単語の境界と見なされます。 したがって、この場合、条件を使用して、 cool-catような文字列の置き換えを回避できます。

'a cat is not a cool-cat'.replace(/\bcat\b/gi,'dog');//wrong
//"a dog is not a cool-dog" -- nips
'a cat is not a cool-cat'.replace(/(?:\b([^-]))cat(?:\b([^-]))/gi,'$1dog$2');
//"a dog is not a cool-cat"

基本的に、この質問はここでの質問と同じです。Javascriptは「」を「」に置き換えます。

@マイク、私がそこで与えた答えを確認してください...正規表現は、それから遠く離れた、subsrtingの複数のオカレンスを置き換える唯一の方法ではありません。 柔軟に考え、分割して考えてください!

var newText = "the cat looks like a cat".split('cat').join('dog');

あるいは、単語の部分の置き換えを防ぐために-承認された回答でも同様です! この問題は、正規表現を使用して回避できます。正規表現は、多少複雑であり、その結果として、少し遅くなります。

var regText = "the cat looks like a cat".replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");

出力は受け入れられた回答と同じですが、次の文字列で/ cat / g式を使用します。

var oops = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/cat/g,'dog');
//returns "the dog looks like a dog, not a dogerpillar or cooldog" ?? 

確かに、これはおそらくあなたが望むものではありません。 では、何ですか? IMHO、条件付きで「猫」を置き換えるだけの正規表現。 (つまり、単語の一部ではありません)、次のように:

var caterpillar = 'the cat looks like a cat, not a caterpillar or coolcat'.replace(/(?:(^|[^a-z]))(([^a-z]*)(?=cat)cat)(?![a-z])/gi,"$1dog");
//return "the dog looks like a dog, not a caterpillar or coolcat"

私の推測では、これはあなたのニーズを満たしています。 もちろん、それは完全な証拠ではありませんが、始めるには十分なはずです。 これらのページでもう少し読むことをお勧めします。 これは、特定のニーズを満たすためにこの表現を完成させるのに役立ちます。

http://www.javascriptkit.com/jsref/regexp.shtml

http://www.regular-expressions.info


最終追加:

この質問はまだ多くのビューを取得しているので、コールバック関数で使用される.replace例を追加するかもしれないと思いました。 この場合、式が劇的に単純化され、正しい大文字で置き換える、またはcatcats両方を一度に置き換えるなど、さらに柔軟性があります。

'Two cats are not 1 Cat! They\'re just cool-cats, you caterpillar'
   .replace(/(^|.\b)(cat)(s?\b.|$)/gi,function(all,char1,cat,char2)
    {
       //check 1st, capitalize if required
       var replacement = (cat.charAt(0) === 'C' ? 'D' : 'd') + 'og';
       if (char1 === ' ' && char2 === 's')
       {//replace plurals, too
           cat = replacement + 's';
       }
       else
       {//do not replace if dashes are matched
           cat = char1 === '-' || char2 === '-' ? cat : replacement;
       }
       return char1 + cat + char2;//return replacement string
    });
//returns:
//Two dogs are not 1 Dog! They're just cool-cats, you caterpillar
scronide picture
2009年05月07日
72

グローバル正規表現との照合:

anotherString = someString.replace(/cat/g, 'dog');
Indrajeet Singh picture
2019年05月29日
64

1回限りの使用を交換する場合:

var res = str.replace('abc', "");

複数回交換するには:

var res = str.replace(/abc/g, "");
Adnan Toky picture
2019年03月25日
60

これらは最も一般的で読みやすい方法です。

var str = "Test abc test test abc test test test abc test test abc"

方法1:

str = str.replace(/abc/g, "replaced text");

方法2:

str = str.split("abc").join("replaced text");

方法3:

str = str.replace(new RegExp("abc", "g"), "replaced text");

方法4:

while(str.includes("abc")){
    str = str.replace("abc", "replaced text");
}

出力:

console.log(str);
// Test replaced text test test replaced text test test test replaced text test test replaced text
SolutionYogi picture
2009年07月18日
45
str = str.replace(/abc/g, '');

または、ここからreplaceAll関数を試してください。

組み込みオブジェクトを拡張する便利なJavaScriptメソッドは何ですか?

str = str.replaceAll('abc', ''); OR

var search = 'abc';
str = str.replaceAll(search, '');

編集: replaceAllの可用性に関する説明

'replaceAll'メソッドがStringのプロトタイプに追加されます。 これは、すべての文字列オブジェクト/リテラル​​で使用できることを意味します。

例えば

var output = "test this".replaceAll('this', 'that');  //output is 'test that'.
output = output.replaceAll('that', 'this'); //output is 'test this'