Pregunta JavaScript: referencias regexales de cadenas


Puede hacer una referencia inversa como esta en JavaScript:

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

Esto sería (bastante tonto) reemplazar "$ test" con "prueba". Pero imagine que me gustaría pasar la cadena resultante de $ 2 en una función, que devuelve otro valor. Intenté hacer esto, pero en vez de obtener la cadena "prueba", obtengo "$ 2". ¿Hay una manera de lograr esto?

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

76
2018-03-15 14:44


origen


Respuestas:


Me gusta esto:

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

105
2018-03-15 14:51



Pasar una función como segundo argumento para replace:

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

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

Esta capacidad ha existido desde Javascript 1.3, de acuerdo con mozilla.org.


28
2018-03-15 14:52



Nota: A la respuesta anterior le faltaba algo de código. Ahora está fijo + ejemplo.


Necesitaba algo un poco más flexible para una regex replace para decodificar el Unicode en mis datos entrantes de JSON:

var text = "some string with an encoded 's' in it";

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

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

0
2018-02-24 12:58



Usando ESNext, es bastante un sustituto de enlaces ficticios, pero solo para mostrar cómo funciona:

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
2018-06-08 18:54



Si tuviera una cantidad variable de referencias, entonces el recuento de argumentos (y lugares) también son variables. los Documentos web de MDN describe la siguiente sintaxis para separar una función como argumento de reemplazo:

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

Por ejemplo, tome estas expresiones regulares:

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

Aquí no puede usar la variable 'arguments' porque es de tipo Arguments y no de tipo Array entonces no tiene una slice() método.


0
2017-07-05 14:45