我想创建一个简单的文本模板,允许使用
{0}
定义占位符,类似于 .Net 使用 string.format 方法。
基本上我想要这个:
format("{0}", 42), // output `42`
format("{0} {1}", 42, "bar"), // output `42 bar`
format("{1} {1}", 42, "bar"), // output `bar bar` ({0} ignored)
format("{{0", 42), // output `{0` (`{{` is an escaped `{`)
format("{{{0}", 42), // output `{42` : an escaped brace and the formatted value
format("Mix {{0}} and {0}", 42), // outputs `Mix {0} and 42`
我正在尝试使用正则表达式和回溯来处理转义的大括号。
function format(template: string, ...values: unknown[]): string {
const regex = /(?!({{)+){(\d+)}(?<!(}}))/gm;
return template.replace(regex, ([, index]) => {
const valueIndex = parseInt(index, 10);
if (valueIndex >= values.length) throw new Error("Not enough arguments")
return String(values[valueIndex]);
});
}
console.log([
format("{0}", 42), // output `42`
format("{0} {1}", 42, "bar"), // output `42 bar`
format("{1} {1}", 42, "bar"), // output `bar bar` ({0} ignored)
format("{{0", 42), // output `{0` (`{{` is an escaped `{`)
format("{{{0}", 42), // output `{42` : an escaped brace and the formatted value
format("Mix {{0}} and {0}", 42), // outputs `Mix {0} and 42`
]);
try {
format("{0} {1}", 42); // throw error because not enough argument are passed
} catch (e) {
console.error(e);
}
但是,我正在努力用单个大括号正确替换逃逸的大括号
如何解决?
你可以使用
(?<=(?<!\{)(?:\{\{)*)\{\d+}(?!(?:}})*}(?!}))
请参阅 正则表达式演示。
详情:
(?<=(?<!\{)(?:\{\{)*)\{
- 未转义的 {
字符(不能有 {
后跟零个或多个双 {
字符)\d+
}(?!(?:}})*}(?!}))
- 未转义的 }
字符(}
前面不能有零个或多个双 }
字符).replaceAll('{{','{').replaceAll('}}','}')
部分完成变形。
查看 JS 演示:
function format(template, ...values) {
const regex = /(?<=(?<!\{)(?:\{\{)*)\{\d+}(?!(?:}})*}(?!}))/g;
return template.replace(regex, ([, index]) => {
const valueIndex = parseInt(index, 10);
if (valueIndex >= values.length) throw new Error("Not enough arguments")
return String(values[valueIndex]).replaceAll('{{','{').replaceAll('}}','}');
});
}
console.log([
format("{0}", 42), // output `42`
format("{0} {1}", 42, "bar"), // output `42 bar`
format("{1} {1}", 42, "bar"), // output `bar bar` ({0} ignored)
format("{{0", 42), // output `{0` (`{{` is an escaped `{`)
format("{{{0}", 42), // output `{42` : an escaped brace and the formatted value
format("Mix {{0}} and {0}", 42), // outputs `Mix {0} and 42`
]);
try {
format("{0} {1}", 42); // throw error because not enough argument are passed
} catch (e) {
console.error(e);
}