我从编辑器收到一个字符串,其中包含 HTML 标签,如下所示:
const htmlString = "<div>Account <span contenteditable="false">{{account}}</span></div>.
<div>Hello <span contenteditable="false">{{hello}}</span></div>"
在此内容中,有两个格式为 {{account}} 和 {{hello}} 的变量。
在我的数据库中,我以格式存储变量数据 { key: string, value: string, isDefault: boolean }:
[
{ "key" : "account", "value" : "", "isDefault" : true, },
{ "key" : "hello", "value" : "Hello everyone", "isDefault" : false }
]
首先,我使用一个函数来删除 HTML 标签:
const blockTags = /<(div|h1|h2|h3|h4|h5|h6|p|ul|ol|li|br)[^>]*>/gi;
const inlineTags = /<\/?(span|a|strong|em|b|i|u)[^>]*>/gi;
let content = htmlString.replace(blockTags, '\n').replace(/<\/(div|h1|h2|h3|h4|h5|h6|p)>/gi, '\n');
content = content.replace(inlineTags, '');
content = content.replace(/<[^>]+>/g, '');
content = content.replace(/\n\s*\n/g, '\n').trim();
然后,我提取变量:
const variables = (content.match(/\{\{(.*?)\}\}/gi) || []).map((item) => item.replace(/\{\{|\}\}/g, ''));
最后,我使用一个函数将所有变量替换为数据库中相应的值,如果变量是默认值(isDefault = true),我将根据系统规则根据配置替换为动态值:
const objVariables = variables.reduce((acc, { key, value, isDefault }) => {
acc[key] = { value, isDefault };
return acc;
}, {});
const result = content.replace(/\{\{(.*?)\}\}/g, (match, variable) => {
const variableData = objVariables[variable];
if (variableData && variableData.isDefault) {
if (variable === "account") {
return "ACCOUNT_NAME";
}
}
return variableData ? variableData.value : match;
});
我想用数据库中存储的值替换 HTML 字符串中的所有变量,但我认为我的代码不是最好的解决方案,而且可能很慢。我正在寻找优化的解决方案或任何建议。
我认为你应该迭代你的变量并替换它们(如果在字符串中找到它们)...不需要剥离标签。
const myVariables =
[
{ "key" : "account", "value" : "", "isDefault" : true },
{ "key" : "hello", "value" : "Hello everyone", "isDefault" : false },
];
let myString = myContent.innerHTML;
myVariables.forEach
(
( { key, value, isDefault } ) => myString = myString.replaceAll
(
`{{${key}}}`,
(
( isDefault && ( key === 'account' ) )
? 'ACCOUNT_NAME'
: value ?? key
)
)
);
myContent.innerHTML = myString;
<div id="myContent">
<div>Account <span contenteditable="false">{{account}}</span>.</div>
<div>Hello <span contenteditable="false">{{hello}}</span></div>
</div>
请注意,在上面的示例中,甚至没有触及 html。
const htmlString = `<div>Account <span contenteditable="false">{{account}}</span></div>.
<div>Hello <span contenteditable="false">{{hello}}</span></div>`;
const databaseVariables = [
{ key: "account", value: "", isDefault: true },
{ key: "hello", value: "Hello everyone", isDefault: false },
];
// Step 1: Convert database array into a Map for faster lookups
const variableMap = new Map(databaseVariables.map(item => [item.key, item]));
// Step 2: Function to strip HTML tags while keeping content structure
function stripHtml(html) {
// Replace block tags with newline and inline tags with nothing
return html
.replace(/<(div|h[1-6]|p|br)[^>]*>/gi, '\n') // Block-level elements
.replace(/<\/(div|h[1-6]|p)>/gi, '\n') // Block-level end tags
.replace(/<\/?(span|a|strong|em|b|i|u)[^>]*>/gi, '') // Inline tags
.replace(/\n\s*\n/g, '\n') // Remove excess newlines
.replace(/<[^>]+>/g, '') // Remove remaining tags
.trim();
}
// Step 3: Function to replace variables in content
function replaceVariables(content) {
return content.replace(/\{\{(.*?)\}\}/g, (match, variable) => {
const variableData = variableMap.get(variable);
if (variableData) {
if (variableData.isDefault && variable === "account") {
return "ACCOUNT_NAME";
}
return variableData.value || match;
}
return match;
});
}
const strippedContent = stripHtml(htmlString);
const finalResult = replaceVariables(strippedContent);
console.log(finalResult);