Wir möchten eine Zeichenfolge auf Instanzen des Pipe-Zeichens | aufteilen, aber nicht, wenn diesem Zeichen ein Escape-Zeichen vorangestellt ist, z. \|.

Beispiel: Wir möchten, dass die folgende Zeichenfolge in die folgenden Komponenten aufgeteilt wird

1|2|3\|4|5

1
2
3\|4
5

Ich erwarte, die folgende Javascript-Funktion, split, verwenden zu können, die einen regulären Ausdruck verwendet. Welchen regulären Ausdruck würde ich zum Teilen übergeben? Wir sind plattformübergreifend und möchten nach Möglichkeit aktuelle und frühere Versionen (1 Version zurück) von IE, FF und Chrome unterstützen.

1
MedicineMan 6 Okt. 2012 im 01:31

3 Antworten

Beste Antwort

Führen Sie anstelle einer Aufteilung eine globale Übereinstimmung durch (genau wie ein lexikalischer Analysator):

  • stimmen mit etwas anderem als \\ oder | überein
  • oder mit einem entkommenen Zeichen übereinstimmen

Etwas wie das:

var str = "1|2|3\\|4|5";
var matches = str.match(/([^\\|]|\\.)+/g);

Eine kurze Erklärung: ([^\\|]|\\.) stimmt entweder mit einem beliebigen Zeichen außer '\' und '|' (Muster: [^\\|]) überein oder (Muster: |) mit einem beliebigen Escapezeichen ( Muster: \\.). Das +, nachdem es angewiesen wurde, einmal oder mehrmals mit dem vorherigen übereinzustimmen: Das Muster ([^\\|]|\\.) wird daher einmal oder mehrmals übereinstimmen. Das g am Ende des Regex-Literal weist die JavaScript-Regex-Engine an, das Muster global anstatt nur einmal abzugleichen.

9
Bart Kiers 8 Okt. 2012 im 20:16

Was Sie suchen, ist ein "negativer Blick hinter den passenden regulären Ausdruck".

Das ist nicht schön, aber es sollte die Liste für Sie aufteilen:

var output = input.replace(/(\\)?|/g, function($0,$1){ return $1?$1:$0+'\n';});

Dies nimmt Ihre Eingabezeichenfolge und ersetzt alle '|' Zeichen, denen NICHT unmittelbar ein '\' vorangestellt ist, und diese durch '\ n' Zeichen ersetzen.

1
Andrew Coonce 5 Okt. 2012 im 21:44

Eine Regex-Lösung wurde veröffentlicht, als ich dies untersuchte. Also habe ich einfach einen ohne geschrieben. Ich habe einige einfache Benchmarks durchgeführt und es ist etwas schneller (ich habe erwartet, dass es langsamer ist ...).

Wenn ich ohne Regex verstanden habe, was Sie wünschen, sollte dies den Job machen:

function doSplit(input) {
    var output = [];
    var currPos = 0,
        prevPos = -1;
    while ((currPos = input.indexOf('|', currPos + 1)) != -1) {
        if (input[currPos-1] == "\\") continue;
        var recollect = input.substr(prevPos + 1, currPos - prevPos - 1);
        prevPos = currPos;
        output.push(recollect);
    }
    var recollect = input.substr(prevPos + 1);
    output.push(recollect);
    return output;
}
doSplit('1|2|3\\|4|5'); //returns [ '1', '2', '3\\|4', '5' ]
0
Mamsaac 5 Okt. 2012 im 22:19