PCRE正規表現の場合、[abc]と(a | b | c)の違いは何ですか?
3 に答える
質問のパターンは同じテキストに一致します。実装に関しては、それらはさまざまなオートマトンと副作用(つまり、サブストリングをキャプチャするかどうか)に対応します。
以下のコメントで、GarrettAlbrightは微妙な違いを指摘しています。任意(.|\n)
の文字に[.\n]
一致しますが、リテラルドットまたは改行のいずれかに一致します。ドットは文字クラス内で特別ではなくなりましたが、、、などの他の文字-
、^
および]
などのシーケンスとともに[:lower:]
、文字クラス内で特別な意味を持ちます。あるコンテキストから別のコンテキストへの特別なセマンティクスを保持するように注意する必要がありますが、文字クラスの外部で\1
の古語的な書き方の場合など、それが不可能な場合もあります。$1
文字クラス内では、\1
常に文字SOHと一致します。
文字クラス([...]
)は、いくつかの文字セットの1つに一致するように最適化されており、代替(x|y
)を使用すると、さまざまな長さのより一般的な選択が可能になります。これらの設計原則を念頭に置くと、パフォーマンスが向上する傾向があります。正規表現の実装は、などのソースコード/[abc]/
を有限状態オートマトン(通常はNFA )に変換します。正規表現エンジンとして私たちが考えるのは、多かれ少なかれ、それらのターゲットステートマシンの実行を支援する簿記係です。十分にスマートな正規表現コンパイラは、同等の正規表現に対して同じマシンコードを生成しますが、指数関数的な複雑さが潜んでいるため、一般的なケースではこれは困難で費用がかかります。
正規表現の背後にある理論のわかりやすい紹介については、MarkDominusによる「正規表現のしくみ」をお読みください。より深く研究するために、 PeterLinzによる正式な言語とオートマタの紹介を検討してください。
(グレッグの答えを読んだ後):それらが異なって評価されるかどうかは、あなたがそれらを与えるどんなプログラムにも依存するべきです。チェックしようとしているものを選択してください。有効な文字のプールをチェックしますか、それとも値をチェックしますか。-それは時々同じように見えるかもしれませんが、その背後にある別の意図である可能性があります。次に、あなたの意図を反映するものを選択します。
角かっこを使用したフォームは、特にJITコンパイルが有効になっている場合、PCREを使用するとはるかに高速になります。それはビットセットのビットをチェックしているだけですが、他のビットセットはすべての選択肢について文字を再読み取りします。文字クラスが角かっこ内で使用できることを多くの人が知らず、[az \ s] +の代わりに([az] | \ s)+を使用するため、このようなケースを検出する最適化を考えていました。