Rascal 中正则表达式匹配的大小是否有限制?

Is there a limit to the size of a regex match in Rascal?

在尝试匹配 Java 源文件中的所有多行注释时,我 运行 出现 Whosebug() 错误。当匹配的评论非常大时会发生这种情况。我已经或多或少地确定了 2500 个字符的限制,但这可能是我的环境所特有的。

我正在使用以下表达式来匹配评论:

/<comment:((\/\*([^*]|[\r\n]|(\*+([^*\/]|[\r\n])))*\*+\/))+>/mi

我应该注意匹配的大小是否有一些限制,或者我的正则表达式是否存在缺陷?

我的堆栈跟踪是:

|project://Sevo1/src/Volume.rsc|(985,32,<53,12>,<53,44>): Whosebug()
    at countLines(|project://Sevo1/src/Volume.rsc|(985,33,<53,12>,<53,45>))
    at $root$(|prompt:///|(0,73,<1,0>,<1,73>))

Your regex 不是最优的,因为它包含一个 *-量化的捕获组,该组包含在字符串内相同位置匹配的替代项。您可能会看到 [^*] 匹配除 * 之外的任何字符(即它匹配换行符),然后您有 [\r\n] 也匹配换行符。请注意,您匹配的文本块大部分都是 1 个字符长(与 (\*+([^*\/]|[\r\n])) 匹配的 * 块除外),而正则表达式引擎似乎不能很好地处理这里的任务。

嵌套量词只有在一次匹配较长的块时才有用。将模式重写为

/<comment:\/\*[^*]*\*+(?:[^\/*][^*]*\*+)*\/>/

这样效率会更高。见 regex demo.

详情

  • \/\* - /* 子串
  • [^*]*\*+ - * 以外的 0+ 个字符后跟一个或多个文字 *
  • (?:[^\/*][^*]*\*+)* - 0+ 个序列:
    • [^\/*][^*]*\*+ - 不是 /*(与 [^/*] 匹配)后跟 0+ 个非星号字符([^*]*)后跟一个或多个星号 (\*+)
  • \/ - 收盘 /