Regex pour remplacer tous les premiers caractères de tabulation, chacun avec un seul espace [dupliquer]
Je recherche une expression régulière pour remplacer tous les caractères de tabulation principaux par un seul espace (un espace pour chaque caractère de tabulation principal.
// 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"
Voyez ceci dans un violon js: https://jsfiddle.net/onebcvu4/2/
Réponse D travaille pour moi.
input.replace(/\t/gy, " ")
Mais je ne comprends pas vraiment pourquoi. Surtout parce que, selon la documentation MDN , l'indicateur global (G) doit être ignoré lorsqu'il est utilisé avec un indicateur collant.
Une expression régulière définie à la fois comme persistante et globale ignore l'indicateur global.
Quelqu'un peut-il clarifier ou fournir une autre solution qui fonctionne?
Réponses
Votre réponse D fonctionne (et est assez intelligente) parce que g
et y
ne sont pas exclusives, mais il était raisonnable de penser qu'elles le seraient. Tous les détails sont dans la spécification ici et ici , mais fondamentalement, le g
fait replace
répéter tant qu'il y a une correspondance, et y
signifie que A) l'expression ne correspond qu'à lastIndex
(qui vaut 0 par défaut), et B) lastIndex
n'est pas mis à jour. Vous faites donc correspondre à plusieurs reprises un \t
at lastIndex
et le remplacez jusqu'à ce que vous manquiez de \t
at lastIndex
. Très intelligent.
Si vous ne voulez pas utiliser celui-là, vous pouvez également le faire avec une alternance et un regard positif derrière:
const result = input.replace(/(?:^\t|(?<=^\t*)\t)/g, " ");
Exemple en direct:
const input = "\t\tSome text\t\tcontaining tabs";
const result = input.replace(/(?:^\t|(?<=^\t*)\t)/g, " ");
console.log(JSON.stringify(result));
Ou si vous êtes d'accord pour passer un rappel à replace
, c'est plus simple et n'a pas besoin de regarder en arrière (ce qui est relativement nouveau, ES2018): faites correspondre tous les \t
caractères de début et remplacez-les par une chaîne d'espaces de même longueur:
const result = input.replace(/^(\t+)/, match => " ".repeat(match.length));
Exemple en direct:
const input = "\t\tSome text\t\tcontaining tabs";
const result = input.replace(/^(\t+)/, match => " ".repeat(match.length));
console.log(JSON.stringify(result));