次の正規表現があります:
"(WORD1.*WORD2.*WORD3)|(WORD1.*WORD3.*WORD2)|(WORD2.*WORD1.*WORD3)|(WORD2.*WORD3.*WORD1)|(WORD3.*WORD1. *WORD2)|(WORD3.*WORD2.*WORD1)"
次の単語に一致します:
ワード1ワード2ワード3 ワード1ワード2Bワード3C 単語3単語1単語2 単語1単語2単語3単語1
しかし、次の言葉はそうではありません:
ワード1ワード1ワード2 ワード1ワード1Bワード2C
この正規表現は、任意の順序で 3 つの単語を含む文字列 (WORD1
、WORD2
、WORD3
) を見つけた場合に一致します。
同じことをより多くの単語で実行したいのですが、問題は、単語の数に応じて正規表現のサイズが指数関数的に増大することです。 この問題を解決するために、この正規表現の構築方法を簡素化することは可能でしょうか (サイズが急激に増大することなく)。
すべての文字列を単純に反復処理し、すべてのキーワードを含まないすべての文字列を除外します。
(より簡潔なバージョンは以下のコード スニペットにあります)
###それを試してみてください:###各単語に対して肯定的な先読みを使用できます。
以下のよりパフォーマンスの高いバージョンでは、開始アンカーを指定し、先読みの検証後に 1 つの文字のみと一致します。 OP の要求に応じて、この手法は
matching
でのみ機能し、extraction
では機能しません。前方先読みはゲートのようなもので、括弧内で指定された一致が存在する場合にのみ続行されますが、一致するものを消費したり取得したりすることはありません。常に長さは 0 です。各単語の前に
.*
があるかどうかを「先読み」する場合、単語の順序は関係ありません。各単語が true の場合は、照合に何も使用せずに続行します。 p>コンテンツが一致するかどうかだけを気にする場合、2 つの式の実質的な違いは、所要時間だけです。コンテンツに必要な 3 つの単語のうち 2 つしか含まれていないとします。式を解釈するソフトウェアが試行が無駄であることを認識できない限り、最初の位置で 3 つの単語「failed」を探し、次に 2 番目の位置で「failed」を試行するというように、最後の位置に到達するまで繰り返される可能性があります。上。
# を指定すると、最初の位置のみがチェックされるため、他の不要なチェックにかかる時間を節約できます。末尾から
# を削除すると、コンテンツにすべての単語が存在するかどうかの真/偽の答えを探しているだけの場合に、不必要なキャッチを防ぐことができます。