2

最近、私は正規表現に親しみやすくなり、正規表現を使用して多くのタスクを非常に効率的に処理しています。ほとんどの perl と同様に、TIMTOWTDI は私の判断を曇らせました。等価演算子または結合演算子を使用できる場合があります。ただし、一方を他方よりも使用する方が適切な場合はありますか?

まずは単純化したケース

my $name = 'Chris';
if ($name eq 'Chris') { print 'What a great name!'; }
if ($name =~/^Chris$/) { print 'Yip sure is a great name; }

したがって、この場合、これは最も単純化されており、等式を使用すると入力が少なくなりますが、この単純化された例では、どちらにもメリットがあります。

もう少し複雑な例では

my $name = 'Christopher';
if ($name eq 'Chris' || $name eq 'Christopher') { print 'What a great name!'; }
if ($name =~ /^Chris(?:topher)?$/) { print 'Yip sure is a great name; }

ここでは、結合演算子の入力が少なくなります。ただし、どちらの利点が他の利点よりも優れているかはわかりません。

文字列全体を固定値と一致させて等値演算子を使用する場合、および文字列をパターン (たとえば 5 桁の文字列) と一致させる場合は、/\d{5}/バインド演算子を使用する場合の一般的なルールも同様です。

上記の例でバインディング演算子を使用するのは不適切ですか。これらの例は作り話であり、実際の問題を反映していない可能性があることを理解しています。しかし、彼らは私の質問を説明しようとして私が考えたものでした.

4

3 に答える 3

3

eq正規表現では、その判断を下す前に、コンパイル フェーズと分析が必要になる可能性があるため、演算子のパフォーマンスがわずかに (あったとしても) 向上することを期待します。

したがって、次の場合:

if ($name eq 'Chris') { print 'What a great name!'; }
if ($name =~/^Chris$/) { print 'Yip sure is a great name; }

...最初のステートメントが最も速いと思います。

ただし、2 番目の例では、論理 OR を指定した失敗したケースの合計時間を考慮する必要があります。

if ($name eq 'Chris' || $name eq 'Christopher') { print 'What a great name!'; }
if ($name =~ /^Chris(?:topher)?$/) { print 'Yip sure is a great name; }

…ここでは、カットアンドドライが少なくなります。確かに、eq速いかもしれeqませんが、 backtrack する必要がない正規表現よりも two s の方が高速ですか (この例では)? 確信が持てません。

通常、パフォーマンス上の利点を考慮する必要はありません。したがって、一方が他方よりも「優れている」と主張することはできません。通常、この状況ではコードを明確にすることをお勧めします。しかしeq、正規表現が非常に柔軟である一方で、それは非常に厳しいことを認識することが重要です - 大文字と小文字を区別しない検索、先頭だけへの固定などを可能にします.比較速度が重要なコードにヒットした場合最終的には基準。

于 2013-10-27T20:28:19.217 に答える
1

正規表現の威力は、その可変性に表れています。
正規表現エンジンにテンプレートを与えると、一致する結果がエンジンに「提案」されます。
内部的には、C の "strncmp()" と同じで、Perl で行うのと同じです。つまり、$str eq "asdf" です。どちらもテンプレートです。

しかし、言語だけでは可変性をうまく表現できないため、正規表現エンジンが存在します。

エンジンを "terring" するためのオーバーヘッドがあります。つまり、変数のリセット、状態の追跡などです。
しかしその後、エンジンは、考えられる言語構造のあらゆる組み合わせよりも優れたパフォーマンスを発揮します
。少しではなく、非常に大きな割合で。

于 2013-10-27T21:10:41.207 に答える