改进正则表达式以匹配javascript注释



我使用perlfaq6中给出的正则表达式来匹配和删除javascript注释,但当字符串过长时,会导致分段错误。正则表达式是-

s#/*[^*]**+([^/*][^*]**+)*/|//([^\]|[^n][n]?)*?n|("(\.|[^"\])*"|'(\.|[^'\])*'|.[^/"'\]*)#defined $3 ? $3 : ""#gse;

是否可以对其进行改进以避免分割错误?

[编辑]

长输入:

<ent r="6" t="259" w="252" /><ent r="6" t="257" w="219" />

重复约1000次。

我怀疑问题的部分原因是您的"C代码"与C代码不太像。在C中,不能将序列"放在一对引号之外,例如,单引号或双引号。

我对正则表达式进行了调整,使其可读,并将其包装成一个琐碎的脚本,该脚本会模糊其输入并将正则表达式应用于它:

#!/usr/bin/env perl
### Original regex from PerlFAQ6.
### s#/*[^*]**+([^/*][^*]**+)*/|//([^\]|[^n][n]?)*?n|("(\.|[^"\])*"|'(\.|[^'\])*'|.[^/"'\]*)#defined $3 ? $3 : ""#gse;
undef $/;  # Slurp input
while (<>)
{
    print "raw: $_";
    s%
        /*[^*]**+([^/*][^*]**+)*/    # Simple C comments
     |  //([^\]|[^n][n]?)*?n        # C++ comments, allowing for backslash-newline continuation
     |  (
            "(\.|[^"\])*"             # Double-quoted strings
        |   '(\.|[^'\])*'             # Single-quoted characters
        |   .[^/"'\]*                  # Anything else
        )
     %    defined $3 ? $3 : ""
     %egsx;
    print "out: $_";
}

我取了你的一行非C代码,创建了文件data.1,data.2,data.4,data.8,…,data.1024,每个文件中都有适当的行数。然后我运行了一个计时循环。

$ for x in 1 2 4 8 16 32 64 128 256 512 1024
> do
>     echo
>     echo $x
>     time perl xx.pl data.$x > /dev/null
> done
$

我对输出进行了处理,以便为不同的文件大小提供实时信息:

   1    0m0.022s
   2    0m0.005s
   4    0m0.007s
   8    0m0.013s
  16    0m0.035s
  32    0m0.130s
  64    0m0.523s
 128    0m2.035s
 256    0m6.756s
 512    0m28.062s
1024    1m36.134s

我没有得到核心转储(MacOSX10.7.4上的Perl5.16.0;8GiB主内存)。这确实需要相当长的时间。当它在运行时,它没有生长;在1024行运行期间,它使用了大约13 MiB的"真实"内存和23 MiB的虚拟内存。

我尝试了Perl5.10.0(我在机器上编译过的最旧版本),它使用的"真实"内存略少,基本上是相同的"虚拟"内存,而且速度明显较慢(512为33.3s线1m 53.9s(1024行)。

为了进行比较,我收集了一些放在测试目录中的C代码,创建了一个大约88 KiB的文件,其中3100行是注释行。相比之下,数据1024文件的大小约为77KiB。处理时间在10到20毫秒之间。

摘要

您所拥有的非C源代码是一个非常糟糕的测试用例。Perl不应该崩溃。

您正在使用哪个版本的Perl,在哪个平台上使用?你的机器有多少内存。然而,内存总量不太可能成为问题(在大多数运行Perl的机器上,24MiB不是问题)。如果您有一个非常旧的Perl版本,结果可能会有所不同。


我还注意到正则表达式不处理C编译器必须处理的一些病态的C注释,例如:

/

* Yes, this is a comment *

/
/

/ And so is this

是的,您可以拒绝任何包含此类评论的提交审查代码。

最新更新