置換 JavaScript で文字列のすべてのオカレンスを置き換える方法は?




javascript 空白 文字 置換 (24)

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

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

行うこと

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

上の文字列でabcの最初の出現を取り除くだけのようです。 それをどのように置き換えることができますか?


一重引用符の置き換え:

function JavaScriptEncode(text){
    text = text.replace(/'/g,''')
    // More encode here if required

    return text;
}

注:これは実際のコードでは使用しないでください。

単純なリテラル文字列の正規表現の代わりに、

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

一般的なパターンは

str.split(search).join(replacement)

これは、 replaceAllと正規表現を使用するよりも早くてreplaceAllことがありましたが、現代のブラウザではそれ以上はそうではありません。 したがって、実際のコードではなく、正規表現をエスケープする必要を避けるために、これは実際には高速ハックとしてのみ使用する必要があります。


更新:

更新にはいくらか遅れていますが、私はこの質問に偶然遭遇し、私の以前の答えは私が満足しているものではないことに気付きました。 質問には1つの単語を置き換えることが含まれていたので、単語境界( \b )を使用することは誰も考えられませんでした

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

これは、ほとんどの場合、単語の一部を置き換えることを避ける単純な正規表現です。 しかし、ダッシュはまだ単語の境界とみなされます。 この場合、 cool-catよう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 "" ""を "''"

@Mike、私がそこに与えた答えをチェックする... regexpは、そこから離れたサブレットの複数の出現を置き換える唯一の方法ではありません。 柔軟性を考え、分裂を考えよう!

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は条件付きで 'cat'を置き換える正規表現です。 (つまり、単語の一部ではない)

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

gフラグがセットされた正規表現を使用すると、すべてが置換されます。

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

こちらもご覧ください


これは、 正規表現を使用しない 最も速いバージョンです。

改訂jsperf

replaceAll = function(string, omit, place, prevstring) {
  if (prevstring && string === prevstring)
    return string;
  prevstring = string.replace(omit, place);
  return replaceAll(prevstring, omit, place, string)
}

分割と結合の方法のほぼ2倍の速さです。

ここでのコメントで指摘したように、 replaceAll("string", "s", "ss")変数にplacereplaceAll("string", "s", "ss")ようにplaceが含まplaceいると、これは動作しません。 。

私の再帰的な置き換えには、より高速になるバリアントを持つ別のjsperfがあります( http://jsperf.com/replace-all-vs-split-join/12 )!

  • 2017年7月27日更新:最近リリースされたChrome 59では、RegExpのパフォーマンスが最速になりました。

完全を期すために、私はこれを行うためにどの方法を使うべきか考えなければなりません。 このページの他の回答で示唆されているように、基本的に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);
};

効率性の面で正規表現がどのように裏で働いているか分かりませんでしたが、私は分割に傾き、パフォーマンスを考えずに過去の実装に加わりました。 私は、より効率的で、どれだけの利益を得たのか不思議に思ったとき、それを見つけ出す言い訳として使用しました。

私のChromeのWindows 8マシンでは、正規表現ベースの実装が最も速く分割と結合の実装は53%遅くなりました 。 つまり、私が使用したlorem ipsum入力の正規表現は2倍高速です。

これらの2つの実装をお互いに実行しているこのbenchmarkをチェックしてください。

下の@ThomasLeducや他のコメントで述べたように、 search に正規表現で特殊文字として予約されている特定の文字が含まれていると、正規表現ベースの実装に問題がある可能性があります 。 実装では、呼び出し元が事前に文字列をエスケープするか、 正規表現 (MDN)の表に文字が含まれていない文字列のみを渡すことが前提です。

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

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

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



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

コメントに応じて:

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

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

のコメントに応えて、それをさらに単純化することができます:

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

注:正規表現には特別な(メタ)文字が含まれていfindそのfind 、前処理なしで上記のfind関数で引数を渡すと、それらの文字をエスケープすることは危険です。 これは、 Mozilla Developer Network正規表現に関するJavaScriptガイドで説明されています 。ここでは、次のユーティリティ関数を示しています。

function escapeRegExp(str) {
    return str.replace(/([.*+?^=!:${}()|\[\]\/\\])/g, "\\$1");
}

したがって、上記のreplaceAll()関数をより安全にするために、 replaceAll()もインクルードすると、次のように変更することができます:

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

人々は正規表現の使用について言及していますが、テキストの大文字と小文字を区別せずにテキストを置き換えたい場合は、より良いアプローチがあります。 大文字または小文字のように。 以下の構文を使用する

//Consider below example
originalString.replace(/stringToBeReplaced/gi, '');

//Output will be all the occurrences removed irrespective of casing.

詳しい例はhere参照できhere


ここでは、受け入れられた答えに基づく文字列プロトタイプ関数があります:

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

EDIT

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

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

フィドル: http://jsfiddle.net/cdbzL/ : http://jsfiddle.net/cdbzL/


見つけたいものがすでに文字列に入っていて、正規表現のエスケープを手軽に利用できない場合は、join / splitを使うことができます:

    function replaceMulti(haystack, needle, replacement)
    {
        return haystack.split(needle).join(replacement);
    }

    someString = 'the cat looks like a cat';
    console.log(replaceMulti(someString, 'cat', 'dog'));


//番号の出現数が0になるまで繰り返します。または単にコピー/ペーストします

    function replaceAll(find, replace, str) 
    {
      while( str.indexOf(find) > -1)
      {
        str = str.replace(find, replace);
      }
      return str;
    }

あなたは単に以下の方法を使うことができます

/**
 * Replace all the occerencess of $find by $replace in $originalString
 * @param  {originalString} input - Raw string.
 * @param  {find} input - Target key word or regex that need to be replaced.
 * @param  {replace} input - Replacement key word
 * @return {String}       Output string
 */
function replaceAll(originalString, find, replace) {
  return originalString.replace(new RegExp(find, 'g'), replace);
};

while (str.indexOf('abc') !== -1)
{
    str = str.replace('abc', '');
}

正規表現を使用する:

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

ちょうど/g追加する

document.body.innerHTML = document.body.innerHTML.replace('hello', 'hi');

// Replace 'hello' string with /hello/g regular expression.
document.body.innerHTML = document.body.innerHTML.replace(/hello/g, 'hi');

/gはグローバルを意味します


次の機能が私の仕事です:

String.prototype.replaceAllOccurence = function(str1, str2, ignore) 
{
    return this.replace(new RegExp(str1.replace(/([\/\,\!\\\^\$\{\}\[\]\(\)\.\*\+\?\|\<\>\-\&])/g,"\\$&"),(ignore?"gi":"g")),(typeof(str2)=="string")?str2.replace(/\$/g,"$$$$"):str2);
} ;

次のような関数を呼び出します。

"you could be a Project Manager someday, if you work like this.".replaceAllOccurence ("you", "I");

このコードをブラウザコンソールにコピーして、TESTに貼り付けるだけです。


私はこの方法が好きです(ちょっときれいに見えます):

text = text.replace(new RegExp("cat","g"), "dog"); 

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

anotherString = someString.replace(/cat/g, 'dog');

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

上記の答えよりも私のためにうまくいった。 new RegExp("abc", 'g') )は、テキスト( "abc" )のすべての出現( 'g'フラグ)に一致するRegExpを作成します。 2番目の部分は、あなたの場合空の文字列( "" )に置き換えられるものです。 strは文字列であり、 replace(...)は結果を返しますが上書きは返さないため、オーバーライドする必要があります。 場合によっては、それを使いたいかもしれません。


function replaceAll(str, find, replace) {
  var i = str.indexOf(find);
  if (i > -1){
    str = str.replace(find, replace); 
    i = i + replace.length;
    var st2 = str.substring(i);
    if(st2.indexOf(find) > -1){
      str = str.substring(0,i) + replaceAll(st2, find, replace);
    }       
  }
  return str;
}

すべての 'abc'を 'x'に置き換えたいとします。

let some_str = 'abc def def lom abc abc def'.split('abc').join('x')
console.log(some_str) //x def def lom x x def

私は文字列のプロトタイプを変更するよりも簡単なことについて考えようとしていました。


探している文字列が置換後も存在しないようにするには、ループを使用する必要があります。

例えば:

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

完了したら、あなたはまだ 'テストabc'を持っています!

これを解決する最も単純なループは次のようになります。

var str = 'test aabcbc';
while (str != str.replace(/abc/g, '')){
   str.replace(/abc/g, '');
}

しかし、それは各サイクルごとに交換を2回実行します。 おそらく(投票される危険性がある)おそらく、より効率的だが読みにくい形式のために組み合わせることができます:

var str = 'test aabcbc';
while (str != (str = str.replace(/abc/g, ''))){}
// alert(str); alerts 'test '!

これは、重複した文字列を探すときに特に便利です。
たとえば、「a ,,, b」があり、すべての重複するコンマを削除したい場合。
[その場合、.replace(/、+ / g、 '、')を行うことができますが、ある時点で正規表現は複雑になり、


文字列にabcccような類似のパターンが含まれている場合は、これを使用できます。

str.replace(/abc(\s|$)/g, "")




replace