我使用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次。
答案 0 :(得分:3)
我怀疑问题部分在于你的“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
我没有获得核心转储(Mac OS X 10.7.4上的Perl 5.16.0; 8 GiB主内存)。它确实需要花费大量时间。它在运行时却没有增长;在1024线运行期间,它使用了大约13 MiB的“真实”内存和23 MiB的“虚拟”内存。
我尝试过Perl 5.10.0(我在我的机器上编译的最旧的版本),它使用的“实际”内存略少,基本上是相同的“虚拟”内存,而且速度明显变慢(512为33.3秒) 线; 1024线的1米53.9秒。
为了便于比较,我收集了一些我在测试目录中存在的C代码,以创建大约88 KiB的文件,其中3100行,其中大约200个是评论行。这与data.1024文件的大小相比,大约是77 KiB。处理时间在10到20毫秒之间。
你拥有的非C源代码是一个非常讨厌的测试用例。 Perl不应该崩溃。
您使用的是哪个版本的Perl,以及在哪个平台上?你的机器有多少内存。但是,内存总量不太可能成为问题(在运行Perl的大多数计算机上,24 MiB不是问题)。如果你有一个非常旧版本的Perl,结果可能会有所不同。
我还注意到正则表达式不处理C编译器必须处理的一些病态C注释,例如:
/\
\
* Yes, this is a comment *\
\
/
/\
\
/ And so is this
是的,您拒绝提交包含此类评论的任何提交审核的代码是正确的。