【问题标题】:Find regular expressions查找正则表达式
【发布时间】:2015-12-26 12:40:01
【问题描述】:

是否有现有算法可以在一行有效 JavaScript 代码中查找所有文字正则表达式出现?

鉴于文字正则表达式不能是多行的,我需要检测一行代码中的所有正则表达式,或者更具体地说 - 每个正则表达式的开始和结束索引(如果存在)。

function enumRegex(textLine) {
    // magic happens here;
}

var testLine = 'var regEx1 = /one/; regEx2 = /two/;';

console.log(enumRegex(testLine));

预期输出:索引对数组(找到的每个 RegEx 的开始和结束索引):

[{13,17},{29,33}]

更新: 在玩了这个Is there a regular expression to detect a valid regular expression? 之后,我不确定它是否会起作用。因此,如果有人建议使用正则表达式来检测正则表达式,则需要一个实际有效的示例。我更希望看到一种算法。

【问题讨论】:

  • 1) 使用正则表达式提取 / 之间的内容 2) 将所有提取的字符串提供给 RegExp 构造函数并检查结果是否为正则表达式对象(如果您输入的不是,它将抛出 SyntaxError一个有效的正则表达式)。
  • 至于finding string literals,你需要一个解析器才能得到可靠的结果。
  • 该算法已经在解析器的源代码中公布。
  • 这个问题最终会变成“解析器是如何工作的?”这太宽泛了,因此我投票决定将此问题作为离题结束。
  • @vitaly-t 这个问题的正确答案是“写一个解析器”。这应该给你足够的想法来工作。其他所有事情(例如,为你编写一个真正的解析器)将是太多的努力,并且代表我们需要太多的细节(记住:我们不是来为你编写代码的)。因此,如果“编写解析器”对您来说不够清楚,那么您的问题本质上是“解析器如何工作?”或“我如何编写解析器?”这太宽泛了。

标签: javascript regex


【解决方案1】:

阻止您执行/\/.+\/[a-z]*/g 作为您的正则表达式测试的唯一并发症是......好吧,对于初学者来说,它会找不到自己。它不喜欢转义的反斜杠。

没问题。

/\/(?:\\.|[^\/])+\/[a-z]*/g

那么这个正则表达式有什么作用呢?

  1. 寻找/ - 这是正则表达式的开始...可能!
  2. 寻找其中一个...
    • 反斜杠后跟任何字符(这是我们忽略转义的逻辑,请注意“任何字符”不包括换行符)
    • 或任何不是正斜杠的字符
  3. 找到表示正则表达式结束的/
  4. 查找附加到正则表达式文字的任何修饰符。

然后……完成了!如果这个正则表达式匹配某个东西,那么它找到了看起来像一个正则表达式的东西。但是...这并不是说您找到了 valid 正则表达式。为此,我们需要一些验证。

首先,让我们捕获正则表达式和修饰符:

/\/((?:\\.|[^\/])+)\/([a-z]*)/g

现在,对于每个匹配,我们尝试从中创建一个正则表达式对象:

isValid = true;
try {
    new RegExp(match[1], match[2]);
    // pass suspect regex as first argument, modifiers as second
}
catch(e) {
    isValid = false;
}

所以你的最终代码可能看起来像......

function enumRegex(textLine) {
    var parser = new RegExp("/((?:\\\\.|[^/])+)/([a-z]*)","g");
    // note that rules for escaping are very different in new RegExp than with literals

    var match, results = [];
    while( match = parser.exec(textLine)) {
        try {
            new RegExp(match[1],match[2]);
        }
        catch(e) {
            continue;
        }
        results.push(match[0]);
    }

    return results;
}

值得注意的是,这远非完美无缺。问题包括:

  • var falseMatch = 'var string = "/trololol/";';
  • var falseMatch = '// comment line with a /regex-like substring/derp';
  • var falseMatch = 'var number = 8 / 2 / 2;';/ 2 / 被视为正则表达式)

这些以及更多内容需要比简单的正则表达式更多的内容感知解析。

【讨论】:

  • 在评估您的答案时,我只想再次强调我只查看有效的 JavaScript,我对无效的 RegExp 或无效的 JavaScript 根本不感兴趣。但也感谢您考虑这些情况! :)
  • @vitaly-t 如果不使用递归正则表达式,这是根本无法完成的,这是 JavaScript 引擎不支持的。下一个最佳选择是查找可疑的正则表达式,并使用内置解析器对其进行测试。
  • 在我的代码中,我已经将文本块、注释块和正则表达式彼此分开,因此您的解决方案比您想象的更接近我的需要:)
  • 出于一般目的,这是我接受的一个很好的答案。非常感谢!
  • 我很困惑为什么你会提出一个完整的解决方案,然后指出它不起作用的所有原因。正确答案就是你的最后一句话。
猜你喜欢
  • 2011-08-03
  • 2016-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-06
相关资源
最近更新 更多