4

"string".contains("anotherString")正規表現VSやその他の文字列API呼び出しをいつ使用するかについての一般的なガイドラインがあるかどうか疑問に思いましたか?

上記の決定.contains()は簡単ですが(1回の呼び出しでこれを実行できるのに、なぜ正規表現に煩わされるのか)、実際の生活ではより複雑な選択が必要になります。たとえば、2回の.contains()呼び出しまたは1回の正規表現を行う方がよいでしょうか。

私の経験則では、単一のAPI呼び出しで置き換えることができない限り、常に正規表現を使用することでした。これにより、コードが肥大化するのを防ぐことができますが、特に正規表現が大きくなる傾向がある場合は、コードの可読性の観点からはあまり良くありません。

もう1つの、見過ごされがちな議論は、パフォーマンスです。この正規表現に必要な反復回数(「BigO」など)を知るにはどうすればよいですか?完全な反復よりも速いでしょうか?どういうわけか、誰もが正規表現が5ifステートメントより短く見えると、それはもっと速くなければならないと思い込んでいます。しかし、これは常に当てはまりますか?これは、正規表現を事前にコンパイルできない場合に特に関係があります。

4

4 に答える 4

3

RegexBuddyには、正規表現デバッガーが組み込まれています。これは、正規表現エンジンが一致を見つけるため、または一致を見つけることができないために必要なステップ数を示しています。さまざまな長さの文字列でデバッガーを使用することにより、正規表現の複雑さ(大きなO)を知ることができます。RegexBuddyのヘルプファイルのインデックスで「ベンチマーク」を検索すると、これを解釈するためのヒントがさらに得られます。

正規表現のパフォーマンスを判断するときは、正規表現が一致するものを見つけられない状況をテストすることが特に重要です。線形時間で一致する正規表現を作成するのは非常に簡単ですが、私が壊滅的なバックトラッキングと呼んでいる状況では、指数時間で失敗します。

例として5ifステートメントを使用するために、正規表現は入力文字列を1回スキャンし、、、、またはが検出されたときにone|two|three|four|five少し余分な作業を行います。ただし、文字列に単語が含まれているかどうかをチェックする5 ifステートメントは、単語が見つからない場合、文字列全体を5回検索します。文字列の先頭でifが発生すると、正規表現は即座に一致を検出しますが、最初の4つのifステートメントは、5番目のifステートメントが一致を検出する前に文字列全体を無駄にスキャンします。otffive

于 2010-02-25T02:01:09.937 に答える
3

プロファイラーを使用せずにパフォーマンスを見積もるのは困難です。一般的に、最も論理的に意味があり、理解/読み取りが容易なものを作成するのが最善の戦略です。2つの.contains()呼び出しが論理的に理解しやすい場合は、それがより適切なルートです。正規表現の方が理にかなっている場合は、同じロジックが適用されます。

チームの他の開発者が正規表現を十分に理解していない可能性があることを考慮することも重要です。後で本番環境で.contains()を超える正規表現の使用(またはその逆)がボトルネックとして識別された場合は、両方を試してプロファイルを作成してください。

経験則:読み取り可能なコードを記述し、プロファイラーを使用してボトルネックを特定してから、読み取り可能なコードをより高速なコードに置き換えます。

于 2009-11-25T11:12:37.280 に答える
1

両方のコードを記述し、時間を計ることを強くお勧めします。これを行うのは非常に簡単で、一般的な「経験則」ではなく、問題のドメインに当てはまる非常に具体的な回答が得られます。

Vance Morrisonには、マイクロベンチマークに関する優れた投稿があり、このような質問に簡単に答えられるようにするツールがあります...

http://msdn.microsoft.com/en-us/magazine/cc500596.aspx

私の個人的な「経験則」が必要な場合は、この種のことでは正規表現が遅いことがよくありますが、私を無視して自分で測定する必要があります:-)

パフォーマンス以外の理由で正規表現を引き続き使用する場合は、2つのことをお勧めします。プロファイラー(ANTSなど)を入手して、コードが本番環境でどのように機能するかを確認します。次に、正規表現クックブックのコピーを入手します...

http://www.amazon.co.uk/Regular-Expressions-Cookbook-Jan-Goyvaerts/dp/0596520689/ref=sr_1_1?ie=UTF8&s=books&qid=1259147763&sr=8-1

...正規表現コードを高速化するためのヒントがたくさんあるため。この本のヒントに従って、正規表現コードを10倍最適化しました。

于 2009-11-25T11:12:03.723 に答える
0

答えは(いつものように)それが依存するということです。

あなたの特定のケースでは、代替手段は正規表現「this|that」を実行してから検索を実行することだと思います。この特定の構成は、正規表現の弱点を実際に突き刺します。この場合の「OR」は、サブパターンが何をしようとしているのかを実際には知らないため、簡単に最適化することはできません。最終的に(擬似コードで)同等の処理を実行します。

for( i = 0; i < stringLength; i++ ) {
    if( stringAt pos i starts with "this" )
       found!
    if( stringAt pos i starts with "that" )
       found!
}

それを行うのに遅い方法はほとんどありません。この場合、2つのcontains()呼び出しははるかに高速になります。

一方、:の完全一致は、より適切に".*this.*|.*that.*"最適化される可能性があります。

私にとって、正規表現は、それ以外の方法で実行するコードが複雑または扱いにくい場合に使用する必要があります。したがって、ターゲット文字列内の2つまたは3つの文字列のいずれかを検索する場合は、containsを使用します。ただし、「A」または「B」で始まり、「g」-「m」で終わる単語を検索する場合は、正規表現を使用します。

そして、あなたはあちこちで数サイクルについてそれほど心配することはありません。

于 2009-11-25T11:21:27.603 に答える