0

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回繰り返しました。

4

1 に答える 1

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 秒; 1m 53.9 秒)。 1024 行の場合)。

比較のために、テスト ディレクトリにある C コードをいくつか集めて、約 88 KiB のファイルを作成しました。3,100 行のうち、約 200 行がコメント行でした。これは、約 77 KiB であった data.1024 ファイルのサイズと比較されます。10 ~ 20 ミリ秒かかった処理。

概要

あなたが持っているC以外のソースは、非常に厄介なテストケースになります。Perl がクラッシュすることはありません。

使用している Perl のバージョンとプラットフォームは? マシンに搭載されているメモリの量。ただし、メモリの総量が問題になることはほとんどありません (Perl を実行するほとんどのマシンでは 24 MiB は問題になりません)。非常に古いバージョンの Perl を使用している場合、結果が異なる場合があります。


また、正規表現は、C コンパイラが処理しなければならないいくつかの異常な C コメントを処理しないことにも注意してください。

/\
\
* Yes, this is a comment *\
\
/
/\
\
/ And so is this

はい、そのようなコメントを含むレビューのために提出されたコードを拒否するのは正しいことです。

于 2012-09-08T15:07:58.087 に答える