Regex, um alle führenden Tabulatorzeichen durch ein einzelnes Leerzeichen zu ersetzen [Duplikat]

Nov 24 2020

Ich suche nach einem regulären Ausdruck, um alle führenden Tabulatorzeichen durch ein einzelnes Leerzeichen zu ersetzen (ein Leerzeichen für jedes führende Tabulatorzeichen.

// input text with two leading tab characters and two tab characters elsewhere in the text
var input="     Some text       containing tabs";

// A:
console.log(input.replace(/\t/g, "LEADING_TAB_"));  
// prints: "LEADING_TAB_LEADING_TAB_Some textLEADING_TAB_LEADING_TAB_containing tabs"

// B:
console.log(input.replace(/\t/, "LEADING_TAB_"));  
// prints: "LEADING_TAB_   Some text       containing tabs"

// C:
console.log(input.replace(/^(\t)*/, "LEADING_TAB_"));  
// prints: "LEADING_TAB_Some text      containing tabs"

// D:
console.log(input.replace(/\t/gy, "LEADING_TAB_"));  
// prints: "LEADING_TAB_LEADING_TAB_Some text      containing tabs"

// E:
console.log(input.replace(/\t/y, "LEADING_TAB_"));  
// prints: "LEADING_TAB_   Some text       containing tabs"

Sehen Sie dies in einer js Geige: https://jsfiddle.net/onebcvu4/2/

Antwort D Arbeit für mich.

input.replace(/\t/gy, " ")

Aber ich verstehe nicht wirklich warum. Insbesondere, weil laut MDN-Dokumentation das globale (G) -Flag ignoriert werden sollte, wenn es mit einem Sticky-Flag verwendet wird.

Ein regulärer Ausdruck, der sowohl als klebrig als auch als global definiert ist, ignoriert das globale Flag.

Kann jemand eine andere Lösung finden, die funktioniert?

Antworten

2 T.J.Crowder Nov 24 2020 at 14:46

Ihre Antwort D funktioniert (und ist ziemlich klug), weil gund y nicht exklusiv, aber es war vernünftig zu glauben, dass dies der Fall sein würde. Ausführliche Details finden Sie hier und hier in der Spezifikation , aber im Grunde wiederholen sich die gMarken replace, solange es eine Übereinstimmung gibt, und ybedeuten, dass A) der Ausdruck nur bei lastIndex(standardmäßig 0) übereinstimmt und B) lastIndexnicht aktualisiert wird. Sie passen also wiederholt ein \tat an lastIndexund ersetzen es, bis Ihnen das \tat ausgeht lastIndex. Sehr schlau.

Wenn Sie diesen nicht verwenden möchten, können Sie dies auch mit einem Wechsel und einem positiven Blick nach hinten tun:

const result = input.replace(/(?:^\t|(?<=^\t*)\t)/g, " ");

Live-Beispiel:

const input = "\t\tSome text\t\tcontaining tabs";
const result = input.replace(/(?:^\t|(?<=^\t*)\t)/g, " ");

console.log(JSON.stringify(result));

Oder wenn Sie mit dem Weiterleiten eines Rückrufs replaceeinverstanden sind, ist dies einfacher und erfordert kein Lookbehind (relativ neu, ES2018): Ordnen Sie alle führenden \tZeichen zu und ersetzen Sie sie durch eine Folge von Leerzeichen gleicher Länge:

const result = input.replace(/^(\t+)/, match => " ".repeat(match.length));

Live-Beispiel:

const input = "\t\tSome text\t\tcontaining tabs";
const result = input.replace(/^(\t+)/, match => " ".repeat(match.length));
console.log(JSON.stringify(result));