基于正则表达式的行删除脚本(JS)不起作用
Posted
技术标签:
【中文标题】基于正则表达式的行删除脚本(JS)不起作用【英文标题】:Regex-based line deletion script (JS) not working 【发布时间】:2020-03-23 19:58:27 【问题描述】:我有一个脚本可以读取文件并通过模式比较字符串,如果它返回 false,它将删除 .txt 文件中的行。
这是我的代码
const readline = require('readline');
const lineReplace = require('line-replace')
const fs = require('fs');
const inputFileName = './outputfinal.txt';
const readInterface = readline.createInterface(
input: fs.createReadStream(inputFileName),
);
let testResults = [];
readInterface.on('line', line =>
testResult = test(line);
console.log(`Test result (line #$testResults.length+1): `, testResult);
testResults.push( input: line, testResult );
if (testResult == false)
console.log(`Line #$testResults.length will get deleted from this list`);
lineReplace(
file: './outputfinal.txt',
line: testResults.length,
text: '',
addNewLine: false,
callback: onReplace
);
function onReplace(file, line, text, replacedText)
;
;
);
// You can do whatever with the test results here.
//readInterface.on('close', () =>
// console.log("Test results:", testResults);
//);
function test(str)
let regex = /^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w2,3)+$/; // email regex
str = str.split(",");
// string should be of length 3 with str[1] number of length 7
if(str && str.length === 3 && Number(str[1]) && str[1] )
let temp = str[0].split("-");
// check for 85aecb80-ac00-40e3-813c-5ad62ee93f42 separately.
if(temp && temp.length === 5 && /[a-zA-Z\d]8/.test(temp[0]) && /[a-zA-Z\d]4/.test(temp[1]) && /[a-zA-Z\d]4/.test(temp[2]) && /[a-zA-Z\d]4/.test(temp[3]) && /[a-zA-Z\d]12/.test(temp[4]))
// email regex
if(regex.test(str[2]))
return true;
else
return false;
else
return false
else
return false;
但不工作,返回错误没有这样的文件或目录,我不认为这是做一个 line remover 脚本的正确方法
【问题讨论】:
仅供参考:/^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w2,3)+$/
容易发生灾难性的回溯。无论您在哪里找到此模式,都让他们知道它至少应该是 /^\w+([.-]\w+)*@\w+([.-]\w+)*(\.\w2,3)+$/
如果显示没有这样的文件或目录,请检查文件的路径是否正确。此外,createReadStream 可能只允许您读取,而不是写入。
请provide your input file 以及您预期输出的示例。
另外,不确定这应该做什么: if(str && str.length === 3 && Number(str[1]) && str[1] ) 您是否要检查是否str[1] 是一个数字,还是将其转换为一个数字并检查它是否不为空或未定义?
请看看这些网站:TLD list; valid/invalid addresses; regex for RFC822 email address
【参考方案1】:
首先,如果错误是“没有这样的文件或目录”是因为该文件不存在。请首先检查该文件是否存在于您项目的同一根目录中。
其次,不要使用库“line-replace”,如果你检查代码这会创建一个 tmp 文件并用替换重写所有文件在一个 tmp 中。完成该过程后,tmp 文件将重命名为原始文件。
第三,如果您分析代码,“lineReplace”是异步的。因此有时会尝试同时打开多次文件,然后再次同时写入。这将产生意想不到的结果。
最好的建议是你必须了解 Nodejs 中 File 的工作原理和 Promises (async):
https://nodejs.org/api/fs.html https://developer.mozilla.org/en-US/docs/Web/javascript/Reference/Global_Objects/Promise https://itnext.io/javascript-promises-with-node-js-e8ca827e0ea3如果您看到下一个代码,您将看到接下来的步骤:
创建 tmp 路由 创建 tmp 文件 创建一个承诺: 创建readline
接口
使用 try catch 处理每一行以在出现错误时拒绝
完成该过程后,将 tmp 文件替换为原始文件,使用 try-catch 以在出现错误时拒绝
等待完成promise,如果出错删除tmp文件
const fs = require('fs');
const readline = require('readline');
async function replaceLineWithConditional(pathFile, conditional)
// tmpFile name
const tmpFilePath = `$pathFile.tmp`;
// Create write stream
const tmpStream = fs.createWriteStream(tmpFilePath);
// Process it
const processFile = new Promise((resolve, reject) =>
const rl = readline.createInterface(
input: fs.createReadStream(pathFile),
);
// Process line
rl.on("line", (input) =>
try
if (conditional(input))
tmpStream.write(input); // input
tmpStream.write("\n"); // linejump
catch (err)
// Reject error
reject(err);
);
// Finish
rl.on("close", () =>
try
// Move the tmpFile
tmpStream.close();
fs.renameSync(tmpFilePath, pathFile);
// Resolve it
resolve(true);
catch (err)
// Reject error
reject(err);
);
);
try
// Await the promise
return await processFile;
catch (err)
// Delete the tmp file and throw the error
tmpStream.close();
fs.unlinkSync(tmpFilePath);
throw err;
因此,您可以使用条件函数过程作为回调调用该函数。例如,我想保留所有长度超过 3 且不以“a”开头的行:
// async/await:
await replaceLineWithConditional("./test.txt", (line) =>
return line.length > 3 && /^[^a]/.test(line);
);
// then/catch:
replaceLineWithConditional("./test.txt", (line) =>
return line.length > 3 && /^[^a]/.test(line);
).then(...).catch(...);
输入:
Hi
Hello
abcdef
a
lalalal
输出:
Hello
lalalal
如果您希望文件不要以结束行结束。 (注意:Why should text files end with a newline?)这可能是一个测验问题,以测试fs
库中的知识:)
【讨论】:
以上是关于基于正则表达式的行删除脚本(JS)不起作用的主要内容,如果未能解决你的问题,请参考以下文章