JavaScript - références arrière des expressions régulières de chaîne


93

Vous pouvez revenir en arrière comme ceci dans JavaScript:

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

Cela remplacerait (assez ridicule) "$ test" par "test". Mais imaginez que j'aimerais passer la chaîne résultante de 2 $ dans une fonction, qui renvoie une autre valeur. J'ai essayé de faire cela, mais au lieu d'obtenir la chaîne "test", j'obtiens "$ 2". Y a-t-il un moyen d'y parvenir?

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

Réponses:


117

Comme ça:

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

1
Génial, où puis-je trouver plus d'informations à ce sujet?
quano


11
Cool. Pour clarifier: $1et $2les noms de paramètres choisis par l'utilisateur sont ici (choisis pour imiter les symboles de référence arrière); le - variant! - le nombre de ces paramètres correspond au nombre de groupes de capture dans la regex.
mklement0

34

Passez une fonction comme deuxième argument à replace:

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

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

Cette fonctionnalité existe depuis Javascript 1.3, selon mozilla.org .


1

En utilisant ESNext, un remplaçant de liens factice, mais juste pour montrer comment cela fonctionne:

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

Remarque: il manquait du code dans la réponse précédente. C'est maintenant fixe + exemple.


J'avais besoin de quelque chose d'un peu plus flexible pour un remplacement de regex afin de décoder l'unicode dans mes données JSON entrantes:

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

Si vous avez un nombre variable de références inverses, le nombre d'arguments (et les emplacements) sont également variables. Les documents Web MDN décrivent la syntaxe suivante pour définir une fonction comme argument de remplacement:

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

Par exemple, prenez ces expressions régulières:

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

Vous ne pouvez pas utiliser la variable «arguments» ici car elle est de type Argumentset non de type Arraydonc elle n'a pas de slice()méthode.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.