将变量替换为包含 HTML 的字符串中数据库中的值

问题描述 投票:0回答:2

我从编辑器收到一个字符串,其中包含 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 字符串中的所有变量,但我认为我的代码不是最好的解决方案,而且可能很慢。我正在寻找优化的解决方案或任何建议。

javascript string replace nestjs
2个回答
2
投票

我认为你应该迭代你的变量并替换它们(如果在字符串中找到它们)...不需要剥离标签。

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。


-1
投票
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);
© www.soinside.com 2019 - 2024. All rights reserved.