2010-12-06 12 views
98

は、私は、次の再利用可能にしたかったと言う:文字列変数を使用してJavaScript正規表現を作成することはできますか?

function replace_foo(target, replacement) { 
    return target.replace("string_to_replace",replacement); 
} 

私はこのような何か行う可能性があります:文字列リテラルと

function replace_foo(target, string_to_replace, replacement) { 
    return target.replace(string_to_replace,replacement); 
} 

これは十分に簡単です。しかし、もし私が正規表現でもう少しトリッキーにしたいのであれば?たとえば、すべてを置き換えたいとしますが、string_to_replaceと置き換えたいとします。本能的に私は上のような何かを行うことによって上記を拡張しようとします:

function replace_foo(target, string_to_replace, replacement) { 
    return target.replace(/^string_to_replace/,replacement); 
} 

これは動作していないようです。私の推測では、string_to_replaceは文字列を表す変数ではなく、文字列リテラルであると考えています。文字列変数を使用してJavaScript正規表現を作成することは可能ですか? flagsgまたはiあるnew RegExp(string, flags)があります

function replace_foo(target, string_to_replace, replacement) { 
    var regex = "/^" + string_to_replace + "/"; 
    return target.replace(regex,replacement); 
} 

答えて

153

:すべての可能性であれば、このようなものは素晴らしいことです。だから、

'GODzilla'.replace(new RegExp('god', 'i'), '') 

zilla 
+22

上で最速のことと省略しているようです'/'正規表現の区切り文字もこの形式を使用します。 – cdhowie

+0

ありがとうございます。そしてcdhowie:素晴らしいコメント。私はまず他の方法を試してみた。 – buley

9

これを行うにはnew RegExp(pattern, flags)を使用して、言いました。文字列リテラルをこのコンストラクタに渡すことになるので、すべてのバックスラッシュをエスケープする必要があります。例えば、あなたの正規表現がバックスラッシュにマッチするようにするには、new RegExp('\\\\')と言う必要がありますが、正規表現のリテラルは/\\/である必要があります。これを使用する方法によっては、適切な前処理(特殊文字のエスケープなど)を行わずにそのような関数にユーザー入力を渡すことに注意する必要があります。

+2

この回答は、最も詳細なものではありませんが、私はちょうど1時間だけつかまれた重要な**詳細を言及しています。たとえば、ある単語で始まる単語を探していたので、必要な正規表現は '/ \ b [term] \ B /'ですが、それを構築するには 'new RegExp(" \\ b "+ term +" \\ B ")'となります。小さくても重要な違いですが、正規表現として直接使用することは難しいです** **は期待どおり動作します。 – Byson

97

文字列リテラルでは、これは簡単です。

この例では、最初にの代わりにstring_to_replaceの最初のが置き換えられます。より一般的には、すべての文字列を置換したい場合は、文字列をグローバル(/.../g)RegExpに変換する必要があります。あなたはnew RegExpコンストラクタを使用して文字列からこれを行うことができます。

new RegExp(string_to_replace, 'g') 

これに伴う問題は、文字列リテラル内の任意の正規表現の特殊文字ではなく通常の文字であることの彼らの特別な方法で動作するということです。あなたはそれを修正するためにバックスラッシュエスケープする必要があります。残念ながら、1はあなたが使用することができますそこので、ここで、あなたのためにこれを行うには、組み込み関数ではありませんです。

function escapeRegExp(s) { 
    return s.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') 
} 

も注意してくださいあなたはreplace()で正規表現を使用する場合、置換文字列は現在、あまりにも特殊文字を持っていることを、 $。置換テキストにリテラル$が必要な場合は、これもエスケープする必要があります。

function escapeSubstitute(s) { 
    return s.replace(/\$/g, '$$$$'); 
} 

(四の$のことは、置換文字列-なんてこったそのものですので!)

今、あなたは、正規表現とグローバルな文字列置換を導入することができます。

function replace_foo(target, string_to_replace, replacement) { 
    var relit= escapeRegExp(string_to_replace); 
    var sub= escapeSubstitute(replacement); 
    var re= new RegExp(relit, 'g'); 
    return target.replace(re, sub); 
} 

何の痛み。あなたがしたいすべてがまっすぐ文字列は正規表現の追加なしの部品と交換している場合は幸運なことに、そこに迅速な方法です:

s.split(string_to_replace).join(replacement) 

は...それがすべてです。これはよく理解されているイディオムです。

が、私はそれが何を意味しstring_to_replaceは

以外のすべてを交換したいと言う、あなたは文字列戦に参加していない続きのテキスト全体を交換したいですか? ^は否定ではなく文字列の開始トークンを意味するので、^の置換は確かにこれを行いません。 ^は、[]文字グループの否定のみです。また、否定的な先読み(?!...)もありますが、JScriptではそれに問題がありますので、一般的に回避する必要があります。あなたは文字列「にすべてをアップ」のマッチング、及びマッチング文字列の間の任意の空のストレッチ破棄する機能を使用してみてください

:ここ

var re= new RegExp('(.*)($|'+escapeRegExp(string_to_find)+')') 
return target.replace(re, function(match) { 
    return match[1]===''? match[2] : replacement+match[2]; 
}); 

を、再び、分割は単純かもしれません:

var parts= target.split(string_to_match); 
for (var i= parts.length; i-->0;) 
    if (parts[i]!=='') 
     parts[i]= replacement; 
return parts.join(string_to_match); 
+9

+1、非常に徹底的で、評価が低い。 –

0
私は(それがレジスタを見たが、レジスタを使用して強調されていないfindsが)文字列のハイライトテキストのための非常に良い例を持っていると思う

function getHighlightedText(basicString, filterString) { 

    if ((basicString === "") || (basicString === null) || (filterString === "") || (filterString === null)) return basicString; 

    return basicString.replace(new RegExp(filterString.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\\\$&'), 'gi'), 
     function(match) 
      {return "<mark>"+match+"</mark>"}); 

} 

http://jsfiddle.net/cdbzL/1258/

0

Aこれには本当に簡単な解決策はこれです:

function replace(target, string_to_replace, replacement) { 
    return target.split(string_to_replace).join(replacement); 
} 

すべて

での正規表現の必要はありません。また、最近のブラウザhttps://jsperf.com/replace-vs-split-join-vs-replaceall

関連する問題