【问题标题】:JS: finding regexp literals in codeJS:在代码中查找正则表达式文字
【发布时间】:2014-03-02 19:03:00
【问题描述】:

我正在解析一些 JavaScript 代码,需要获取其中的所有正则表达式。文字符号/\/(.(?:[^\/])|\\)+\/[gmi]*/gi 看起来不错,但在某些情况下它不能正常工作。

例如,对于这段代码:

html = html.replace(/\</g, '&lt;').replace(/\>/g, '&gt;').replace(/\&/g, '&amp;');

match() 给出了两个愚蠢的结果:/\&lt;/g, '&amp;lt;' ).replace( //\&amp;/g

我似乎无法让它工作。

【问题讨论】:

  • 我建议使用真正的 JavaScript 解析器,例如 esprima.org。然后你就可以遍历 AST 并轻松获取所有正则表达式字面量。

标签: javascript regex parsing


【解决方案1】:

你不会使用单个正则表达式来解决这个问题。您现在偶然发现了一个您的正则表达式没有正确处理的极端情况,但还有很多很多。当多行或单行注释中有一个开始的正则表达式文字时,或者当字符串文字内出现/ 时,您的正则表达式将中断。

唯一可靠地解决此问题的方法是解析 JavaScript,并检查解析器(或词法分析器)生成的令牌流。

要开始使用,请参阅:JavaScript parser in JavaScript

user3371384 写道:

我不关心 cmets,因为我在获取正则表达式文字之前删除了它们,字符串也是如此。

不管怎样,还有更多的极端情况:

var e = 8, f = 4, g = 2;
// ...
var x = e/f/g; // your regex will match `/f/g` as a regex literal

user3371384 写道:

在许多代码解析器中使用相同的算法:找到斜线,然后找到下一个斜线(如果它之前没有反斜线),里面的所有字符都是正则表达式。

很可能是这样,但这是一个非常不准确的算法(正如您在上面给出的反例中所看到的那样)。还有速记 /= 可能会弄乱正则表达式。

无论如何,您似乎已经决定为此使用正则表达式...

您将. 放置在错误的位置:您只想匹配反斜杠 之后的任何字符。试试这个:

/\/([^\/]|\\.)+\/[gmi]*/gi

【讨论】:

  • ... 或任何正则表达式嵌套括号表示子正则表达式的地方。真正的重点是正则表达式的符号,它本身并不是正则的。相反,它是上下文无关的。 OP 正在尝试使用正则表达式识别上下文无关结构,但总是注定要失败。是的,他需要一个真正的解析器。
  • 我不关心 cmets,因为我在获取正则表达式文字之前删除了它们,对于字符串也是如此。问题是从代码中获取正则表达式文字[没有 cmets 和字符串]。
  • 在许多代码解析器中使用相同的算法:找到斜杠,然后找到下一个斜杠(如果它之前没有反斜杠),里面的所有字符都是正则表达式。对于我的目的来说,这已经足够好的算法了,/\/(.(?:[^\/])|\\)+\/[gmi]*/gi 似乎是正确的,但实际上并非如此。有什么问题?
  • 谢谢巴特,我说服你绝对正确。这是一个复杂的问题,需要复杂的解决方案。
猜你喜欢
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 2014-05-13
  • 1970-01-01
  • 2016-12-31
  • 1970-01-01
  • 1970-01-01
  • 2013-08-14
相关资源
最近更新 更多