JavaScript - Regex-Rückreferenzen für Zeichenfolgen

93

Sie können in JavaScript wie folgt zurückverweisen:

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

Dies würde (ziemlich dumm) "$ ​​test" durch "test" ersetzen. Aber stellen Sie sich vor, ich möchte die resultierende Zeichenfolge von $ 2 an eine Funktion übergeben, die einen anderen Wert zurückgibt. Ich habe es versucht, aber anstatt den String "test" zu bekommen, bekomme ich "$ 2". Gibt es einen Weg, dies zu erreichen?

// 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
quelle

Antworten:

117

So was:

str.replace(regex, function(match, $1, $2, offset, original) { return someFunc($2); })
SLaks
quelle
1
Super, wo finde ich mehr Infos dazu?
Quano
11
Cool. Zur Verdeutlichung: $1und $2sind hier vom Benutzer ausgewählte Parameternamen (ausgewählt, um die Rückreferenzsymbole nachzuahmen); das - variierend! - Die Anzahl dieser Parameter entspricht der Anzahl der Erfassungsgruppen im regulären Ausdruck.
mklement0
34

Übergeben Sie eine Funktion als zweites Argument an replace:

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

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

Diese Funktion gibt es laut mozilla.org seit Javascript 1.3 .

Sean
quelle
1

Mit ESNext ein ziemlicher Ersatz für Dummy-Links, aber nur um zu zeigen, wie es funktioniert:

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
quelle
0

Hinweis: In der vorherigen Antwort fehlte Code. Es ist jetzt behoben + Beispiel.


Ich brauchte etwas Flexibleres für einen Regex-Ersatz, um den Unicode in meinen eingehenden JSON-Daten zu dekodieren:

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
quelle
0

Wenn Sie eine variable Anzahl von Rückreferenzen haben würden, sind auch die Anzahl der Argumente (und die Stellen) variabel. Die MDN- Webdokumente beschreiben die folgende Syntax zum Trennen einer Funktion als Ersatzargument:

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

Nehmen Sie zum Beispiel diese regulären Ausdrücke:

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

Sie können hier keine 'Argumente'-Variable verwenden, da sie vom Typ Argumentsund keine vom Typ ist und Arraydaher keine slice()Methode hat.

7ochem
quelle