Use string dinâmica (variável) como padrão regex em JavaScript

101

Eu quero adicionar uma tag (variável) a valores com regex, o padrão funciona bem com PHP, mas tenho problemas para implementá-lo em JavaScript.

O padrão é ( valueé a variável):

/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is

Eu escapei das barras invertidas:

var str = $("#div").html();
var regex = "/(?!(?:[^<]+>|[^>]+<\\/a>))\\b(" + value + ")\\b/is";
$("#div").html(str.replace(regex, "<a href='#" + value +">" + value + "</a>"));

Mas isso não parece estar certo, eu registrei o padrão e é exatamente o que deveria ser. Alguma ideia?

Borstenhorst
fonte
É valueuma variável?
Dogbert

Respostas:

173

Para criar o regex a partir de uma string, você deve usar o RegExpobjeto JavaScript .

Se você também deseja corresponder / substituir mais de uma vez, deve adicionar o gsinalizador (correspondência global) . Aqui está um exemplo:

var stringToGoIntoTheRegex = "abc";
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Demonstração do JSFiddle aqui.


No caso geral, escape a string antes de usar como regex:

No entanto, nem toda string é uma regex válida: existem alguns caracteres especiais, como (ou [. Para contornar esse problema, basta escapar da string antes de transformá-la em um regex. Uma função de utilidade para isso está no exemplo abaixo:

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

var stringToGoIntoTheRegex = escapeRegExp("abc"); // this is the only change from above
var regex = new RegExp("#" + stringToGoIntoTheRegex + "#", "g");
// at this point, the line above is the same as: var regex = /#abc#/g;

var input = "Hello this is #abc# some #abc# stuff.";
var output = input.replace(regex, "!!");
alert(output); // Hello this is !! some !! stuff.

Demonstração do JSFiddle aqui.



Nota: a regex na pergunta usa o smodificador, que não existia no momento da pergunta, mas existe - um sinalizador / modificador s( dotall ) em JavaScript - hoje .

acdcjunior
fonte
2
isso é ótimo e o melhor exemplo que encontrei até agora de usar uma variável dinâmica em uma regex, obrigado!
Eolis
1
Para 2019 s modificador, veja novamente o link MDN na nota de resposta.
Nickensoul
@Nickensoul Well spotted! Obrigado pelo aviso!
acdcjunior
deixe idr = novo RegExp (variável + "$"); Table.find ({field: new RegExp (idr, 'i')}) Eu fiz assim. Felicidades.
Utkarsh
12

Se você está tentando usar um valor de variável na expressão, você deve usar o "construtor" RegExp.

var regex="(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b";
new RegExp(regex, "is")
mothmonsterman
fonte
6

Você não precisa do "para definir uma expressão regular, então apenas:

var regex = /(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/is; // this is valid syntax

Se valuefor uma variável e você quiser uma expressão regular dinâmica, não poderá usar esta notação; use a notação alternativa.

String.replace também aceita strings como entrada, então você pode fazer "fox".replace("fox", "bear");

Alternativo:

var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(value)\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(" + value + ")\b/", "is");
var regex = new RegExp("/(?!(?:[^<]+>|[^>]+<\/a>))\b(.*?)\b/", "is");

Lembre-se de que se valuecontém caracteres de expressões regulares como (, [e ?você precisará escapar deles.

idílico
fonte
2
A primeira opção não funcionaria a menos que você
procurasse
@happytimeharry Parece um conflito entre as duas expressões regulares que ele postou.
Halcyon
@Fritz van Campen parece que a intenção do padrão, dado o exemplo de seu javascript, era usar uma variável
mothmonsterman
mesmo problema aqui, parece haver algo errado com o sinalizador "é": "Uncaught SyntaxError: Sinalizadores inválidos fornecidos ao construtor RegExp 'é'"
Borstenhorst
os sinalizadores para o construtor de RegExp precisam ser separados. Mas ainda assim o regex não está funcionando.
Borstenhorst
5

Achei este tópico útil - então pensei em adicionar a resposta ao meu próprio problema.

Eu queria editar um arquivo de configuração de banco de dados (datastax cassandra) de um aplicativo de nó em javascript e para uma das configurações no arquivo eu precisava combinar em uma string e, em seguida, substituir a linha seguinte.

Esta foi a minha solução.

dse_cassandra_yaml='/etc/dse/cassandra/cassandra.yaml'

// a) find the searchString and grab all text on the following line to it
// b) replace all next line text with a newString supplied to function
// note - leaves searchString text untouched
function replaceStringNextLine(file, searchString, newString) {
fs.readFile(file, 'utf-8', function(err, data){
if (err) throw err;
    // need to use double escape '\\' when putting regex in strings !
    var re = "\\s+(\\-\\s(.*)?)(?:\\s|$)";
    var myRegExp = new RegExp(searchString + re, "g");
    var match = myRegExp.exec(data);
    var replaceThis = match[1];
    var writeString = data.replace(replaceThis, newString);
    fs.writeFile(file, writeString, 'utf-8', function (err) {
    if (err) throw err;
        console.log(file + ' updated');
    });
});
}

searchString = "data_file_directories:"
newString = "- /mnt/cassandra/data"

replaceStringNextLine(dse_cassandra_yaml, searchString, newString );

Após a execução, ele mudará a configuração do diretório de dados existente para o novo:

arquivo de configuração antes de:

data_file_directories:  
   - /var/lib/cassandra/data

arquivo de configuração após:

data_file_directories:  
- /mnt/cassandra/data
JRD
fonte
4

Descobri que tinha que cortar duas vezes o \ b para fazê-lo funcionar. Por exemplo, para remover palavras "1x" de uma string usando uma variável, eu precisava usar:

    str = "1x";
    var regex = new RegExp("\\b"+str+"\\b","g"); // same as inv.replace(/\b1x\b/g, "")
    inv=inv.replace(regex, "");
vai
fonte
Funcionou para mim. Obrigado,
Pravin Bhapkar
1

Maneira muito mais fácil: use literais de modelo.

var variable = 'foo'
var expression = `.*${variable}.*`
var re = new RegExp(expression, 'g')
re.test('fdjklsffoodjkslfd') // true
re.test('fdjklsfdjkslfd') // false
Alec Donald Mather
fonte
0
var string = "Hi welcome to stack overflow"
var toSearch = "stack"

//case insensitive search

var result = string.search(new RegExp(toSearch, "i")) > 0 ? 'Matched' : 'notMatched'

https://jsfiddle.net/9f0mb6Lz/

Espero que isto ajude

Vinu
fonte