使用md5 grunt任务生成md5文件名。现在我想用任务回调中的新文件名重命名HTML文件中的源。我想知道最简单的方法是什么。


当前回答

您可以使用流在读取文件时处理该文件。这就像使用缓冲区,但使用了更方便的API。

var fs = require('fs');
function searchReplaceFile(regexpFind, replace, cssFileName) {
    var file = fs.createReadStream(cssFileName, 'utf8');
    var newCss = '';

    file.on('data', function (chunk) {
        newCss += chunk.toString().replace(regexpFind, replace);
    });

    file.on('end', function () {
        fs.writeFile(cssFileName, newCss, function(err) {
            if (err) {
                return console.log(err);
            } else {
                console.log('Updated!');
            }
    });
});

searchReplaceFile(/foo/g, 'bar', 'file.txt');

其他回答

ES2017/8 for Node 7.6+,带有用于原子替换的临时写文件。

const Promise = require('bluebird')
const fs = Promise.promisifyAll(require('fs'))

async function replaceRegexInFile(file, search, replace){
  let contents = await fs.readFileAsync(file, 'utf8')
  let replaced_contents = contents.replace(search, replace)
  let tmpfile = `${file}.jstmpreplace`
  await fs.writeFileAsync(tmpfile, replaced_contents, 'utf8')
  await fs.renameAsync(tmpfile, file)
  return true
}

注意,仅适用于较小的文件,因为它们将被读入内存。

你也可以使用'sed'函数,它是ShellJS的一部分…

 $ npm install [-g] shelljs


 require('shelljs/global');
 sed('-i', 'search_pattern', 'replace_pattern', file);

完整的文档…

ShellJS - sed() ShellJS

<p>请点击下面的{{link}}验证账号</p>


function renderHTML(templatePath: string, object) {
    const template = fileSystem.readFileSync(path.join(Application.staticDirectory, templatePath + '.html'), 'utf8');
    return template.match(/\{{(.*?)\}}/ig).reduce((acc, binding) => {
        const property = binding.substring(2, binding.length - 2);
        return `${acc}${template.replace(/\{{(.*?)\}}/, object[property])}`;
    }, '');
}
renderHTML(templateName, { link: 'SomeLink' })

当然,您可以改进读取模板函数,将其作为流读取,并按行组合字节,使其更有效

这可能会帮助到一些人:

这与全局替换略有不同

我们从终端运行 节点replace.js

replace.js:

function processFile(inputFile, repString = "../") {
var fs = require('fs'),
    readline = require('readline'),
    instream = fs.createReadStream(inputFile),
    outstream = new (require('stream'))(),
    rl = readline.createInterface(instream, outstream);
    formatted = '';   

const regex = /<xsl:include href="([^"]*)" \/>$/gm;

rl.on('line', function (line) {
    let url = '';
    let m;
    while ((m = regex.exec(line)) !== null) {
        // This is necessary to avoid infinite loops with zero-width matches
        if (m.index === regex.lastIndex) {
            regex.lastIndex++;
        }
        
        url = m[1];
    }

    let re = new RegExp('^.* <xsl:include href="(.*?)" \/>.*$', 'gm');

    formatted += line.replace(re, `\t<xsl:include href="${repString}${url}" />`);
    formatted += "\n";
});

rl.on('close', function (line) {
    fs.writeFile(inputFile, formatted, 'utf8', function (err) {
        if (err) return console.log(err);
    });

});
}


// path is relative to where your running the command from
processFile('build/some.xslt');

这就是它的作用。 我们有几个文件有xml:includes

然而,在开发过程中,我们需要向下移动的路径。

从这个

<xsl:include href="common/some.xslt" />

这个

<xsl:include href="../common/some.xslt" />

因此,我们最终运行两个regx模式,一个用于获取href,另一个用于写入 也许有更好的方法,但目前是有效的。

谢谢

我在用一串大代码替换一个小占位符时遇到了问题。

我正在做:

var replaced = original.replace('PLACEHOLDER', largeStringVar);

我发现问题出在JavaScript的特殊替换模式上,如下所述。由于我使用的代码作为替换字符串有一些$,它是混乱的输出。

我的解决方案是使用函数替换选项,它不做任何特殊替换:

var replaced = original.replace('PLACEHOLDER', function() {
    return largeStringVar;
});