JavaScript ` 在编写大字符串时非常有用。我的问题是它考虑了 JavaScript 中前面的空白量。因此,如果您的字符串在 JavaScript 中缩进,那么它在字符串中也会缩进。有什么办法可以摆脱这个吗?
因为在这样的示例中,我希望 html 标签与字符串的左侧齐平,但我不想使其与 JavaScript 的左侧齐平。检查 console.log 结果如何,以便更好地理解它。
MyFunction = function() {
console.log(`
<html>
<head>
</head>
<body>
</body>
</html>
`);
}
MyFunction();
控制台.log:
因为您希望它们
html
标签与左侧齐平,但仍然希望 head
和 body
相对缩进,所以您要寻找的是将每行开头的 4 个空格替换为一个空字符串。
string.replace(/^ {4}/gm, '')
这是实时代码..
MyFunction = function() {
console.log(`
<html>
<head>
</head>
<body>
</body>
</html>
`.replace(/^ {4}/gm, ''));
}
MyFunction();
使用简单的正则表达式来查找字符串的初始缩进可以通过
/^[\r\n]?(\s+)/
来完成 - 结果可用于再次对初始缩进进行逐行替换。这也利用了 JS RegExp 的性能。
如果您还想删除第一个和最后一个换行符,只需在字符串替换后添加
.trim()
。
function trimLeadingWS(str) {
/*
Get the initial indentation
But ignore new line characters
*/
var matcher = /^[\r\n]?(\s+)/;
if(matcher.test(str)) {
/*
Replace the initial whitespace
globally and over multiple lines
*/
return str.replace(new RegExp("^" + str.match(matcher)[1], "gm"), "");
} else {
// Regex doesn't match so return the original string
return str;
}
};
MyFunction = function() {
console.log(trimLeadingWS('nothing to trim'));
console.log(trimLeadingWS(`
really
quite
some
of (amount of spaces after line break should be ignored)
indent
to
remove
`));
console.log(trimLeadingWS(`
<html>
<head>
</head>
<body>
</body>
</html>
`));
}
MyFunction();
我会做以下事情:
MyFunction = function() {
/*however many spaces you want to remove from the front*/
const spaces = ' '; // four spaces
/* or */
const spacesRegex = /\s+/g;
let str = '';
const html = `
<html>
<head>
</head>
<body>
</body>
</html>
`.split('\n')
.forEach(line=>{
str += line.replace(spaces, '') + '\n';
});
console.log(str);
}
您可以
match
换行后的空格并获取第一行的长度。由此您可以构建一个可以替换它们的正则表达式:
let MyFunction = function(str) {
let matches = str.match(/ +/g)
let initial = matches[0].length // how big is the indent
let re = RegExp(`\n {${initial}}`, 'g') // remove these at the beginning of lines
return str.replace(re, '\n')
}
let str = `
<html>
<head>
</head>
<body>
<div>
some text
</div>
</body>
</html>
`
console.log(MyFunction(str))
您可以按
\n
分割文本,在第一个相关行中找到缩进并将其从行的其余部分中删除,然后再次加入。
MyFunction = function () {
let indent = "";
console.log(`
<html>
<head>
</head>
<body>
</body>
</html>
`.split("\n").reduce((lines, line) => {
if (!indent.length && line.trim()) {
indent = line.match(/^(\s+)/)[0];
}
lines.push(line.replace(indent, ""));
return lines;
}, []).filter(line => line.length).join("\n"));
};
MyFunction();
当然,有一千种方法可以到达目的地。要仅使内容的缩进消失,您可以对模板字符串使用以下方法。这确保只有模板字符串创建的缩进消失,但基本格式保持不变。
function trimIndent(strings, ...values) {
const result = new Array(strings.length);
result[0] = strings[0].replace(/^\n/, '');
const endIndex = strings.length - 1;
result[endIndex] = strings[endIndex].replace(/\n$/, '');
var indent = result[0].match(/^\s+/g);
result[0] = result[0].replace(/^\s+/, '');
for (let i = 0, m = result.length; i < m; i++) {
var input = result[i] ?? strings[i];
result[i] = input.replace(new RegExp('\n' + indent, "gm"), '\n');
}
return result.flatMap((value, index) => {
return value + (index < values.length ? values[index] : '')
}).join("");
}
// example call:
var user = {
id: 10,
name: "Kevin",
}
if (true) {
console.log(trimIndent`
<div>
<span>ID: ${user.id}</span>
<span>
Username: ${user.name}
</span>
</div>
`);
}
TypeScript 解决方案,删除字符串中常见的缩进:
/**
* Remove common indentation from a string
* @param str The string to deindent
* @param tabSize The size of the tab
* @returns The deindented string
*/
export function deindent(strings: TemplateStringsArray, { tabSize = 2 } = {}) {
let str = strings.join('');
str = str.replace(/\t/g, ' '.repeat(tabSize));
const maxCommonIndent = str
.split('\n')
.filter((line) => line.trim() !== '')
.map((line) => line.match(/^ */)![0].length)
.reduce((max, indent) => Math.max(max, indent), 0);
return str
.split('\n')
.map((line) => line.slice(maxCommonIndent))
.join('\n');
}
示例:
function deindent(strings, { tabSize = 2 } = {}) {
let str = strings.join('');
str = str.replace(/\t/g, ' '.repeat(tabSize));
const minCommonIndent = str
.split('\n')
.filter((line) => line.trim() !== '')
.map((line) => line.match(/^ */)[0].length)
.reduce((min, indent) => Math.min(min, indent), Infinity);
return str
.split('\n')
.map((line) => line.slice(minCommonIndent))
.join('\n');
}
console.log(deindent`
<html>
<head>
</head>
<body>
<div>
Hello World!
</div>
</body>
</html>
`);