1

なぜそのような正規表現のコンパイルがRAMの最大70%を占め、激しいスワッピングと平均16の負荷につながるのか疑問に思っています。

strcpy(regexStr,"^[a-z]{0,20000}$" );
regcomp( &regex , regexStr , REG_NOSUB | REG_EXTENDED );

実行時間は数分のオーダーです(前にプロセスを強制終了する必要がありました)。(20,000ではなく2,000)の実行^[a-z]{0,2000}$は約100msであり、これは私にとって非常に重要です。

これを使ってパターンをチェックすると同時に、長さもチェックします。Ï正規表現は両方にとって便利であることがわかりました。私は何か間違ったことをしていますか?

4

4 に答える 4

10

文字列の長さを測定するために使用し、その後、非アルファ文字がないことをテストするためにstrlen正規表現を使用することをお勧めします。/[^a-z]/接吻。

ところで、いいえ、なぜそのようなパフォーマンスが得られているのか、正当な理由はわかりません*。

*正当な理由には、明らかにバグや設計の悪さは含まれません...

編集:結局のところ、実際には設計が不十分な場合があります

edit2: 実行しているチェックは非常に単純なので、実際にはプレーン C で実装できます:

int i;
for (i=0; i<20000 && str[i]!=0; i++)
  if (str[i] < 'a' || str[i] > 'z')
    return -1;
return i;

-1 を返す場合、文字列には az の範囲外の文字が含まれています。20000 を返す場合、文字列は 20000 文字を超えています。それ以外の場合は、文字列の長さを返します。(注: これは明らかに非ワイド char 文字列でのみ機能します)

于 2011-02-04T16:03:59.090 に答える
4

オッズは、内部で正規表現エンジンがパターンを^(|[a-z]|[a-z][a-z]|[a-z][a-z][a-z]|..)$、範囲のカーディナリティが 2 次のようなものに変換していることです。

于 2011-02-04T16:08:14.960 に答える
1

私の推測では、カーディナリティの範囲があなたを殺しているのです。"^[a-z]*$"最大長チェックと組み合わせて、 などの貪欲な非特定カーディナリティ マッチを使用してみてください。それははるかに速いはずです。

于 2011-02-04T16:07:12.627 に答える
0

コンパイラに何を求めているのかを考慮する必要があります。単純に言えば、正規表現のコンパイルは、正規表現に一致する文字列のみを受け入れる有限状態マシンの構築であると考えることができます。文字列に含まれる文字数を追跡する必要があるマシンの状態サイズを考えてみると、現在の正規表現の問題がわかるはずです。

于 2011-02-04T16:06:13.683 に答える