【问题标题】:Replace markup in file without writing new file替换文件中的标记而不写入新文件
【发布时间】:2017-03-06 14:24:04
【问题描述】:

我在一个文件中有 HTML 标记。我打算挑选那个标记,根据数据集替换其中的占位符,并返回一个合并的字符串。我可以简单地使用服务器端模板(我以前做过),但现在买不起,因为某些客户端代码需要相同的前端代码标记,即超出public/ 的代码。目前,只要运行到 exec 函数,服务器就会挂起,并且不会抛出任何 console.errors。

代码如下所示

 var availableFoodsString = "",
regexCb = function (dataSet, flag, indexPage) {
    return function(match, $1, index) {
        if (indexPage == undefined && dataSet["username"] != undefined) {
            dataSet["username_search"] = dataSet["username"];
        }

        if (dataSet[$1] != undefined) return dataSet[$1];

        else if (flag == "EMPTY") return "";
        else if (flag == "MATCH") return match;
    }
}; 


foodsModel.find({availableToday: true}, function(err, docs) {
    if (err) throw err;

    docs.forEach(function (doc) {
        doc = doc.toObject();
        doc.image = "/images/food/" + doc.name + ".jpg";

        var template = /(<div class="food-menu">(\s*.*)*<\/div>)/gi.exec(fs.readFileSync("public/index.html").toString())[0]
        availableFoodsString += template.replace(/\{\{(\w+)\}\}/gi, regexCb(doc))
    });
}); 

本质上,我需要在一天结束时将availableFoodsString 作为附加值呈现给另一个占位符,即render({available: availableFoodsString})。

public/index.html 是一个普通的 HTML,介于两者之间

{{名称}}

{{价格}}

添加到购物车

因此,一些 jQuery 代码在 DOM 完全加载后的某个时间点也需要这种令人垂涎的标记,而模型中的 doc 包含名称和价格填充变量。

foodsModel.find() 函数是异步的,是的,但它是在 http.createServer 函数内部由数据库打开连接回调调用的,因此此时肯定会加载变量。

我见过一些其他解决方案,例如this 和相关问题,但它们都涉及从 npm 请求一些外部模块,或者从匹配的标记写入新文件,然后替换并合并到所需的变量中。我知道必须有一种方法可以在没有这些的情况下实现这一目标。

【问题讨论】:

  • 看起来您正在尝试重新创建一个客户端框架,例如 AngularJS 或 Knockout。
  • 申请已经完成。只是最近包含的一项功能需要在登录页面上转储模板。您会同意,从一开始就使用这些功能中的任何一个进行重建都是一种过度杀伤,类似于用大锤杀死一只苍蝇。如果遇到最坏的情况,我可以将它们放在单独的文件中,并使用 AJAX 在前端加载模板。我只是想我可以找到更优雅的东西。
  • @adam0101 * 你会同意,我的意思是从一开始就使用任何那些框架* 进行重构。不是“功能”。我无法编辑评论,因为 SO 的编辑按钮使用 Ajax,这在我的手机上不起作用,很遗憾。

标签: javascript regex node.js rendering


【解决方案1】:

问题与我的正则表达式有关。第二个括号有罪,称为catastrophic backtracking。这意味着比赛是贪婪的,让解释器陷入地狱,即收回超过需要的东西,而不是根据需要反向给予。我在正则表达式上敲了几个点,现在一切都可以无缝运行了。

旧代码保持不变,只是正则表达式改变了:

/(&lt;div class="food-menu"&gt;(\s*.*)*&lt;\/div&gt;)/gi

到这里:

/(&lt;div class="food-menu"&gt;(\s+.*)+&lt;\/div&gt;)/g

由于某种原因,以前的正则表达式似乎与文件字符串无缝匹配,这是我第一次测试它,但一旦我将其插入实际代码中,它就变得残酷无情。

【讨论】:

    猜你喜欢
    • 2017-06-30
    • 1970-01-01
    • 1970-01-01
    • 2020-04-08
    • 2021-11-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多