NodeJS无效的正则表达式:无重复[重复]

kzmpq1sx  于 12个月前  发布在  Node.js
关注(0)|答案(3)|浏览(141)

此问题在此处已有答案

Regex error when using {1}+ possessive quantifier in JavaScript regex(1个答案)
3天前关闭。
我尝试在nodejs中解析spawn的aria2c输出。Regex101显示表达式应该可以工作,但node却不这么说。我不确定我在这一点上错过了什么。
表达式(.*?)\[NOTICE\]+[Download complete\:\s]+[A-Za-z0-9\/.]{15}+(.*)
尝试解析输出01/02 22:48:36 [NOTICE] Download complete: ./tmp/torrents/Test
节点

const config = require('./.config.js');
const fs = require('fs');
const async = require('async');
const utils = require('./libs/utils.js');
const request = require('request').defaults({ headers: { 'User-Agent': utils.randomUserAgent() } });
const spawn = require('child_process').spawn;
const stripAnsi = require('strip-ansi');

let url = 'https://files.catbox.moe/7swab3.torrent';

request.head({
    url: url,
    timeout: 20 * 1000,
    followAllRedirects: true,
    followOriginalHttpMethod: true
}, (err, response, body) => {
    if (err) {
        return console.log(utils.REMOTE_STATUS.ERROR, 'Unable to make initial request');
    }

    let tmpFilename = false;
    let downloadPath = config.torrents_dir;
    let aria2c = spawn('/usr/bin/aria2c', [ '--dir=' + downloadPath, '--seed-time=0', url ]);

    console.log(utils.REMOTE_STATUS.DOWNLOADING, 'Download started');

    aria2c.stdout.on('data', (execData) => {
        let cleaned = stripAnsi(execData.toString());

        let finishCheck = cleaned.match(/(.*?)\[NOTICE\]+[Download complete\:\s]+[A-Za-z0-9\/.]{15}+(.*)/);
        
        if (finishCheck) {
            tmpFilename = true;
            console.log(finishCheck[2])
        }
    });

    aria2c.on('close', (code) => {
        if (code.toString() !== '0' || tmpFilename === false) {
            return console.log(utils.REMOTE_STATUS.ERROR, 'Download failed');
        }

        console.log(utils.REMOTE_STATUS.DOWNLOADED, 'Download finished');
    });
});

字符串
误差

/home/ryahn/sites/multi/test.js:75
        let finishCheck = cleaned.match(/(.*?)\[NOTICE\]+[Download complete\:\s]+[A-Za-z0-9\/.]{15}+(.*)/);
                                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^


Regex101 Regex101

9ceoxa92

9ceoxa921#

这里似乎有一些误解:

  • [ ]只匹配 * 一个 * 字符,它可以是该字符类中的任何字符。没有 * 顺序 *。因此[Download complete\:\s]+不仅匹配“Download complete:“,还匹配“w”,或“cwt”或“DDDDDDDDD”。
  • \]+不仅匹配一个文字],而且可能匹配多个文字。
  • 您得到的错误消息涉及{15}+中的+:它在那里没有意义。

假设你想在示例中输出“Test”,将相关代码行改为:

let finishCheck = cleaned.match(/(.*?)\s+\[NOTICE\]\s+Download complete:\s.*?([^\s\/]*)$/);

字符串
除了上面提到的更正,.*?将跳过下载文件名的路径部分,因为下一个捕获组要求最后的字符不包含正斜杠:([^\s\/]*)$$Assert您已经到达输入字符串的结尾。

tjvv9vkg

tjvv9vkg2#

看起来问题可能出在正则表达式上。让我们简化一下。尝试使用这个调整后的正则表达式:

let finishCheck = cleaned.match(/(.*?)\[NOTICE\]\s+Download complete:\s+([A-Za-z0-9\/.]{15}.*)/);

字符串
此版本删除了匹配组后面的+,并添加了\s+来匹配元素之间的一个或多个白色空格。在代码中尝试给予这个调整后的正则表达式,看看它是否解决了aria2c输出所面临的解析问题。

wyyhbhjk

wyyhbhjk3#

你似乎想做的是尝试获得正确的文件名?为此,你可以使用内置的path库,如下所示:

// up in the import/requires
const path = require("path");

//back to your code
let cleaned = stripAnsi(execData.toString());

if (cleaned.includes("Download complete")) {
    tmpFilename = true;
    let filePath = cleaned.split(" ").pop()
    console.log(path.basename(filePath))
}

字符串
这将给予您文件名^^
或者,如果你想继续使用正则表达式,
我看了一下你的正则表达式,看起来最后的+(在你的量词之后)是导致问题的原因,试试这个正则表达式:
/(.*?).\[NOTICE\]+[Download complete\:]+[A-Za-z0-9\/.]{15}(.*)/
此外,对于你的日期/时间匹配在一开始,它也包括一个额外的空格,所以包括出组,我只是排除了一个字符接近年底从第一组匹配。
看看现在还能不能用

相关问题