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"));
quano
la source

Réponses:

117

Comme ça:

str.replace(regex, function(match, $1, $2, offset, original) { return someFunc($2); })
SLaks
la source
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 .

Sean
la source
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;

vdegenne
la source
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"
Jacksonkr
la source
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.

7ochem
la source