すべての先頭のタブ文字を1つのスペースに置き換える正規表現[重複]

Nov 24 2020

すべての先頭のタブ文字を単一のスペース(先頭のタブ文字ごとに1つのスペース)に置き換える正規表現を探しています。

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

jsフィドルでこれを参照してください: https://jsfiddle.net/onebcvu4/2/

回答Dは私のために働きます。

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

しかし、私はその理由を本当に理解していません。特に、MDNのドキュメントによると、スティッキーフラグと一緒に使用する場合は、グローバル(G)フラグを無視する必要があるためです。

スティッキーとグローバルの両方として定義された正規表現は、グローバルフラグを無視します。

誰かがうまくいく別の解決策を明確にしたり提供したりできますか?

回答

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

あなたの答えDは動作します(とはかなり賢いです)ので、gy されない排他的な、しかし、彼らがことだと思うのが妥当でした。詳細はこことここの仕様にありますが、基本的には一致する限り繰り返しgます。つまり、A)式はでのみ一致し(デフォルトは0)、B)は更新されません。繰り返しと一致するそうで、あなたはアウトの実行まで、それを置き換えるに。非常に賢い。replaceylastIndexlastIndex\tlastIndex\tlastIndex

それを使用したくない場合は、交互に使用して、前向きな見方をすることもできます。

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

実例:

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

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

または、にコールバックを渡しても問題replaceがない場合は、より簡単で、後読みする必要はありません(比較的新しい、ES2018):すべての先頭\t文字を照合し、同じ長さのスペースの文字列に置き換えます。

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

実例:

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