JavaScript - stringhe regex backreferences


93

Puoi eseguire il backreference in questo modo in JavaScript:

var str = "123 $test 123";
str = str.replace(/(\$)([a-z]+)/gi, "$2");

Questo (abbastanza sciocco) sostituirebbe "$ test" con "test". Ma immagina di voler passare la stringa risultante di $ 2 in una funzione, che restituisce un altro valore. Ho provato a farlo, ma invece di ottenere la stringa "test", ottengo "$ 2". C'è un modo per raggiungere questo obiettivo?

// Instead of getting "$2" passed into somefunc, I want "test"
// (i.e. the result of the regex)
str = str.replace(/(\$)([a-z]+)/gi, somefunc("$2"));

Risposte:


117

Come questo:

str.replace(regex, function(match, $1, $2, offset, original) { return someFunc($2); })

1
Fantastico, dove posso trovare maggiori informazioni su questo?
quano


11
Freddo. Per chiarire: $1e $2sono qui i nomi dei parametri scelti dall'utente (scelti per imitare i simboli di backreference); il - variabile! - il numero di questi parametri corrisponde al numero di gruppi di cattura nella regex.
mklement0

34

Passa una funzione come secondo argomento a replace:

str = str.replace(/(\$)([a-z]+)/gi, myReplace);

function myReplace(str, group1, group2) {
    return "+" + group2 + "+";
}

Questa funzionalità è disponibile da Javascript 1.3, secondo mozilla.org .


1

Utilizzando ESNext, un sostituto di collegamenti fittizi, ma solo per mostrare come funziona:

let text = 'Visit http://lovecats.com/new-posts/ and https://lovedogs.com/best-dogs NOW !';

text = text.replace(/(https?:\/\/[^ ]+)/g, (match, link) => {
  // remove ending slash if there is one
  link = link.replace(/\/?$/, '');
  
  return `<a href="${link}" target="_blank">${link.substr(link.lastIndexOf('/') +1)}</a>`;
});

document.body.innerHTML = text;


0

Nota: nella risposta precedente mancava del codice. Ora è corretto + esempio.


Avevo bisogno di qualcosa di un po 'più flessibile per una sostituzione di regex per decodificare l'unicode nei miei dati JSON in arrivo:

var text = "some string with an encoded '&#115;' in it";

text.replace(/&#(\d+);/g, function() {
  return String.fromCharCode(arguments[1]);
});

// "some string with an encoded 's' in it"

0

Se si dispone di una quantità variabile di riferimenti a ritroso, anche il conteggio degli argomenti (e le posizioni) sono variabili. I documenti Web MDN descrivono la seguente sintassi per separare una funzione come argomento sostitutivo:

function replacer(match[, p1[, p2[, p...]]], offset, string)

Ad esempio, prendi queste espressioni regolari:

var searches = [
    'test([1-3]){1,3}',  // 1 backreference
    '([Ss]ome) ([A-z]+) chars',  // 2 backreferences
    '([Mm][a@]ny) ([Mm][0o]r[3e]) ([Ww][0o]rd[5s])'  // 3 backreferences
];
for (var i in searches) {
    "Some string chars and many m0re w0rds in this test123".replace(
        new RegExp(
            searches[i]
            function(...args) {
                var match = args[0];
                var backrefs = args.slice(1, args.length - 2);
                // will be: ['Some', 'string'], ['many', 'm0re', 'w0rds'], ['123']
                var offset = args[args.length - 2];
                var string = args[args.length - 1];
            }
        )
    );
}

Non puoi usare la variabile 'arguments' qui perché è di tipo Argumentse non di tipo, Arrayquindi non ha un slice()metodo.

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.