Você pode criar regexes JavaScript dinamicamente usando variables ​​de string?

Digamos que eu queira fazer o seguinte reutilizável:

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

Eu poderia fazer algo assim:

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

Com literais de string isso é bastante fácil. Mas e se eu quiser ficar um pouco mais complicado com o regex? Por exemplo, digamos que eu queira replace tudo, mas string_to_replace . Instintivamente eu tentaria estender o acima, fazendo algo como:

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

Isso não parece funcionar. Meu palpite é que ele acha que string_to_replace é uma string literal, em vez de uma variável que representa uma string. É possível criar regexes JavaScript dinamicamente usando variables ​​de string? Algo assim seria ótimo se fosse possível:

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

Há um new RegExp(string, flags) onde os flags são g ou i . assim

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

avalia para

 zilla 

Com literais de string isso é bastante fácil.

Na verdade não! O exemplo só substitui a primeira ocorrência de string_to_replace . Mais comumente você deseja replace todas as ocorrências e, nesse caso, é necessário converter a string em um RegExp global ( /.../g ). Você pode fazer isso a partir de uma string usando o new RegExp construtor new RegExp :

 new RegExp(string_to_replace, 'g') 

O problema com isso é que qualquer caractere regex-especial na string literal se comportará de maneira especial, em vez de caracteres normais. Você teria que sair da barra invertida para corrigir isso. Infelizmente, não há uma function interna para fazer isso para você, então aqui está uma que você pode usar:

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

Note também que quando você usa um RegExp em replace() , a string de substituição agora também tem um caractere especial $ . Isso também deve ser escapado se você quiser ter um $ literal em seu texto de substituição!

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

(Four $ s porque é uma string de substituição – argh!)

Agora você pode implementar a substituição global de strings com o RegExp:

 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); } 

Que dor. Felizmente, se tudo o que você quer fazer é uma substituição de seqüência de caracteres reta sem partes adicionais de regex, há uma maneira mais rápida:

 s.split(string_to_replace).join(replacement) 

…e isso é tudo. Este é um idioma comumente entendido.

digamos que eu queira replace tudo, mas string_to_replace

O que isso significa, você quer replace todos os trechos de texto que não participam de uma correspondência contra a string? Um substituto com … certamente não é isso, porque ^ significa um token de início de cadeia, não uma negação. ^ é apenas uma negação em grupos de caracteres [] . Há também lookaheads negativos (?!...) , mas há problemas com isso no JScript, portanto, você deve evitá-lo.

Você pode tentar corresponder ‘tudo até’ a string e usar uma function para descartar qualquer trecho vazio entre as strings correspondentes:

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

Aqui, novamente, uma divisão pode ser mais simples:

 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); 

Como os outros disseram, use o new RegExp(pattern, flags) para fazer isso. Vale a pena notar que você estará passando literais de string para este construtor, portanto, todas as barras invertidas terão que ser escapadas. Se, por exemplo, você quisesse que seu regex correspondesse a uma barra invertida, você precisaria dizer new RegExp('\\\\') , enquanto o literal regex só precisaria ser /\\/ . Dependendo de como você pretende usar isso, você deve ser cauteloso ao passar a input do usuário para tal function sem o pré-processamento adequado (caracteres especiais, etc.). Sem isso, seus usuários podem obter alguns resultados muito inesperados.

Sim você pode.

https://developer.mozilla.org/en/JavaScript/Guide/Regular_Expressions

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

Eu acho que tenho muito bom exemplo para realçar texto em string (ele não acha que está olhando para o registrador, mas destacado usando o registrador)

 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 ""+match+""}); } 

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

Uma solução realmente simples para isso é esta:

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

Não há necessidade de Regexes em tudo

Ele também parece ser o mais rápido em navegadores modernos https://jsperf.com/replace-vs-split-join-vs-replaceall