Come si usa una variabile in un'espressione regolare?


1380

Vorrei creare un String.replaceAll()metodo in JavaScript e sto pensando che usare una regex sarebbe il modo più conciso per farlo. Tuttavia, non riesco a capire come passare una variabile a una regex. Posso già fare questo che sostituirà tutte le istanze di "B"con"A" .

"ABABAB".replace(/B/g, "A");

Ma voglio fare qualcosa del genere:

String.prototype.replaceAll = function(replaceThis, withThis) {
    this.replace(/replaceThis/g, withThis);
};

Ma ovviamente questo sostituirà solo il testo "replaceThis"... quindi come posso passare questa variabile alla mia stringa regex?


9
Tieni presente che stiamo lavorando per aggiungere questa funzionalità a JavaScript se hai un'opinione al riguardo, partecipa alla discussione.
Benjamin Gruenbaum,

Risposte:


1842

Invece di usare la /regex/gsintassi, puoi costruire un nuovo oggetto RegExp :

var replace = "regex";
var re = new RegExp(replace,"g");

Puoi creare dinamicamente oggetti regex in questo modo. Quindi farai:

"mystring".replace(re, "newstring");

272
Se è necessario utilizzare un'espressione come /\/word\:\w*$/, essere sicuri di sfuggire tuoi backslash: new RegExp( '\\/word\\:\\w*$' ).
Jonathan Swinney,

2
@gravityboy Puoi fare ('' + myNumber) .replace (/ 10 / g, 'a') o se vuoi numeri esadecimali, puoi fare parseInt ('' + myNumber, 16) per convertire in esadecimali da decimali.
Eric Wendelin,

29
La domanda suggerisce che RegEx viene utilizzato solo per effettuare una sostituzione costante della stringa. Quindi questa è una risposta sbagliata in quanto fallirebbe se la stringa contiene meta caratteri RegEx. Purtroppo è votato così in alto, farà
venire

16
Un esempio del passaggio di una variabile renderebbe questa una buona risposta. Sto ancora lottando dopo aver letto questo.
Goose,

3
@JonathanSwinney: /non ha alcun significato speciale se costruisci regex dalla stringa, quindi non devi scappare. /\/word\:\w*$/dovrebbe esserenew RegExp('/word\\:\\w*$')
Dávid Horváth l'

211

Come ha detto Eric Wendelin, puoi fare qualcosa del genere:

str1 = "pattern"
var re = new RegExp(str1, "g");
"pattern matching .".replace(re, "regex");

Questo cede "regex matching .". Tuttavia, fallirà se str1 è"." . Ti aspetteresti che il risultato sia "pattern matching regex", sostituendo il periodo con "regex", ma si rivelerà essere ...

regexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregexregex

Questo perché, sebbene "."sia una stringa, nel costruttore RegExp è ancora interpretata come un'espressione regolare, che significa qualsiasi carattere senza interruzione di riga, ovvero ogni carattere nella stringa. A tale scopo, può essere utile la seguente funzione:

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

Quindi puoi fare:

str1 = "."
var re = new RegExp(RegExp.quote(str1), "g");
"pattern matching .".replace(re, "regex");

cedendo "pattern matching regex".


4
Sai che il primo parametro da sostituire può essere una stringa normale e non deve essere una regexp? str1 = "."; alert ("pattern matching.". replace (str1, "string"));
circa il

@some: ovviamente. Questo perché l'esempio sopra è banale. Quando è necessario cercare o sostituire un modello combinato con una stringa normale, eseguire str.match (nuovo RegExp ("https?: //" + RegExp.escape (myDomainName)), ad esempio. È fastidioso che la funzione di escape sia non integrato.
Gracenotes il

(continua) Inoltre, apparentemente JC Grubbs ha richiesto una sostituzione globale; l'implementazione di una sostituzione globale con String.replace (String, String) potrebbe essere lenta per input di grandi dimensioni. Sto solo dicendo che le prime due soluzioni sono difettose e falliranno inaspettatamente su determinati input.
Gracenotes il

4
developer.mozilla.org/en-US/docs/JavaScript/Guide/… offre una funzione simile, ma esclude -e include =!:/.
Chbrown,

8
Il termine corretto è "fuga", non "citazione". Solo a proposito.
Lawrence Dol,

118

"ABABAB".replace(/B/g, "A");

Come sempre: non usare regex a meno che non sia necessario. Per una semplice sostituzione di stringa, il linguaggio è:

'ABABAB'.split('B').join('A')

Quindi non devi preoccuparti dei problemi di quotazione menzionati nella risposta di Gracenotes.


11
E hai misurato che questo è più veloce di regex?
Mitar,

3
Questo sembra preferibile, specialmente quando è necessario abbinare caratteri regex speciali come '.'
Krease

1
Uhm ... Non divide anche prendere un RegExp; in tal caso, non causerebbe lo stesso problema? Comunque ... .split (). Join () potrebbe essere più lento su alcune piattaforme, perché sono due operazioni, mentre .replace () è un'operazione e può essere ottimizzato.

5
@ PacMan--: entrambi splite replacepossono prendere una stringa o un RegExpoggetto. Il problema che replaceha quel splitnon lo fa è che quando si utilizza una stringa si ottiene solo una singola sostituzione.
Bobince,


38

Se vuoi ottenere TUTTE le occorrenze ( g), fai distinzione tra maiuscole e minuscole ( i) e usa i limiti in modo che non sia una parola all'interno di un'altra parola ( \\b):

re = new RegExp(`\\b${replaceThis}\\b`, 'gi');

Esempio:

let inputString = "I'm John, or johnny, but I prefer john.";
let replaceThis = "John";
let re = new RegExp(`\\b${replaceThis}\\b`, 'gi');
console.log(inputString.replace(re, "Jack")); // I'm Jack, or johnny, but I prefer Jack.

grazie! (afaict, la tua è l'unica risposta esplicita con rxinterpolazione Emacs / -style, tramite stringhe di template.)
sam boosalis

34

Per chiunque cerchi di usare la variabile con il metodo match , questo ha funzionato per me

var alpha = 'fig';
'food fight'.match(alpha + 'ht')[0]; // fight


20
this.replace( new RegExp( replaceThis, 'g' ), withThis );

Mi piace questa risposta in quanto non crea la variabile extra (e inutile).
Wick,

14

Volete costruire l'espressione regolare in modo dinamico e per questo il solutuion corretto è usare il new RegExp(string)costruttore. Affinché il costruttore tratti letteralmente i caratteri speciali , è necessario sfuggirli. Esiste una funzione integrata nel widget di completamento automatico dell'interfaccia utente jQuery chiamata $.ui.autocomplete.escapeRegex:

[...] puoi utilizzare la $.ui.autocomplete.escapeRegexfunzione integrata. Prenderà un singolo argomento stringa e sfuggirà a tutti i caratteri regex, rendendo sicuro il risultato da passare new RegExp().

Se stai usando l'interfaccia utente di jQuery puoi usare quella funzione o copiarne la definizione dall'origine :

function escapeRegex( value ) {
    return value.replace( /[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&" );
}

E usalo in questo modo:

"[z-a][z-a][z-a]".replace(new RegExp(escapeRegex("[z-a]"), "g"), "[a-z]");
//            escapeRegex("[z-a]")       -> "\[z\-a\]"
// new RegExp(escapeRegex("[z-a]"), "g") -> /\[z\-a\]/g
// end result                            -> "[a-z][a-z][a-z]"

9
String.prototype.replaceAll = function (replaceThis, withThis) {
   var re = new RegExp(replaceThis,"g"); 
   return this.replace(re, withThis);
};
var aa = "abab54..aba".replaceAll("\\.", "v");

Prova con questo strumento


5
String.prototype.replaceAll = function(a, b) {
    return this.replace(new RegExp(a.replace(/([.?*+^$[\]\\(){}|-])/ig, "\\$1"), 'ig'), b)
}

Provalo come:

var whatever = 'Some [b]random[/b] text in a [b]sentence.[/b]'

console.log(whatever.replaceAll("[", "<").replaceAll("]", ">"))

4

Ecco un'altra sostituzione Tutta l'implementazione:

    String.prototype.replaceAll = function (stringToFind, stringToReplace) {
        if ( stringToFind == stringToReplace) return this;
        var temp = this;
        var index = temp.indexOf(stringToFind);
        while (index != -1) {
            temp = temp.replace(stringToFind, stringToReplace);
            index = temp.indexOf(stringToFind);
        }
        return temp;
    };

4

E la versione da caffè della risposta di Steven Penny, dato che questo è il risultato google n. 2 .... anche se il caffè è solo javascript con molti caratteri rimossi ...;)

baz = "foo"
filter = new RegExp(baz + "d")
"food fight".match(filter)[0] // food

e nel mio caso particolare

robot.name=hubot
filter = new RegExp(robot.name)
if msg.match.input.match(filter)
  console.log "True!"

perché un downvote? coffeescript -IS- javascript con la sua sintassi specifica.
appassionato del

robot.name=hubotnon è JavaScript.
codepleb

3

Mentre puoi creare RegExp creato dinamicamente (come per le altre risposte a questa domanda), farò eco al mio commento da un post simile : La forma funzionale di String.replace () è estremamente utile e in molti casi riduce la necessità di oggetti RegExp creati dinamicamente. (che è un po 'una seccatura perché devi esprimere l'input al costruttore RegExp come una stringa piuttosto che usare il formato letterale slash / [AZ] + / regexp)


3

Per soddisfare la mia necessità di inserire una variabile / alias / funzione in un'espressione regolare, ecco cosa mi è venuto in mente:

oldre = /xx\(""\)/;
function newre(e){
    return RegExp(e.toString().replace(/\//g,"").replace(/xx/g, yy), "g")
};

String.prototype.replaceAll = this.replace(newre(oldre), "withThis");

dove "oldre" è la regexp originale in cui voglio inserire una variabile, "xx" è il segnaposto per quella variabile / alias / funzione e "yy" è il nome, l'alias o la funzione attuale della variabile.


2

Puoi usarlo se $ 1 non funziona con te

var pattern = new RegExp("amman","i");
"abc Amman efg".replace(pattern,"<b>"+"abc Amman efg".match(pattern)[0]+"</b>");

1

Puoi sempre usare indexOfripetutamente:

String.prototype.replaceAll = function(substring, replacement) {
    var result = '';
    var lastIndex = 0;

    while(true) {
        var index = this.indexOf(substring, lastIndex);
        if(index === -1) break;
        result += this.substring(lastIndex, index) + replacement;
        lastIndex = index + substring.length;
    }

    return result + this.substring(lastIndex);
};

Questo non va in un ciclo infinito quando la sostituzione contiene la corrispondenza.


1

La tua soluzione è qui:

Passa una variabile all'espressione regolare.

Quello che ho implementato è prendendo il valore da un campo di testo che è quello che vuoi sostituire e un altro è il campo di testo "Sostituisci con", ottenendo il valore dal campo di testo in una variabile e impostando la variabile su RegExp funzione per sostituire ulteriormente. Nel mio caso sto usando Jquery, puoi anche farlo solo con JavaScript.

Codice JavaScript:

  var replace =document.getElementById("replace}"); // getting a value from a text field with I want to replace
  var replace_with = document.getElementById("with"); //Getting the value from another text fields with which I want to replace another string.

  var sRegExInput = new RegExp(replace, "g");    
  $("body").children().each(function() {
    $(this).html($(this).html().replace(sRegExInput,replace_with));
  });

Questo codice si trova nell'evento Onclick di un pulsante, puoi inserirlo in una funzione da chiamare.

Quindi ora puoi passare la variabile nella funzione di sostituzione.


La tua variabile repl_with conterrà l'elemento DOM e non il valore stesso
Ben Taliadoros,

1

Questa funzione di chiamata automatica eseguirà l'iterazione su replacerItems utilizzando un indice e cambierà replacerItems [indice] a livello globale sulla stringa con ogni passaggio.

  const replacerItems = ["a", "b", "c"];    

    function replacer(str, index){
          const item = replacerItems[index];
          const regex = new RegExp(`[${item}]`, "g");
          const newStr = str.replace(regex, "z");
          if (index < replacerItems.length - 1) {
            return replacer(newStr, index + 1);
          }
          return newStr;
    }

// console.log(replacer('abcdefg', 0)) will output 'zzzdefg'

0

Nessuna di queste risposte mi era chiara. Alla fine ho trovato una buona spiegazione su http://burnignorance.com/php-programming-tips/how-to-use-a-variable-in-replace-function-of-javascript/

La semplice risposta è:

var search_term = new RegExp(search_term, "g");    
text = text.replace(search_term, replace_term);

Per esempio:

$("button").click(function() {
  Find_and_replace("Lorem", "Chocolate");
  Find_and_replace("ipsum", "ice-cream");
});

function Find_and_replace(search_term, replace_term) {
  text = $("textbox").html();
  var search_term = new RegExp(search_term, "g");
  text = text.replace(search_term, replace_term);
  $("textbox").html(text);
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textbox>
  Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum Lorem ipsum
</textbox>
<button>Click me</button>


1
Stai sovrascrivendo una variabile di chiusura, non è necessario utilizzarla varqui. Inoltre, se passi \bo \1si romperà.
CyberAP

0

Per la sostituzione multipla senza espressioni regolari sono andato con il seguente:

      let str = "I am a cat man. I like cats";
      let find = "cat";
      let replace = "dog";


      // Count how many occurrences there are of the string to find 
      // inside the str to be examined.
      let findCount = str.split(find).length - 1;

      let loopCount = 0;

      while (loopCount < findCount) 
      {
        str = str.replace(find, replace);
        loopCount = loopCount + 1;
      }  

      console.log(str);
      // I am a dog man. I like dogs

La parte importante della soluzione è stata trovata qui

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.