@
、、、#
および任意の数字を含むテキストを照合する必要があります。文字は、テキスト内にある限り、ランダムな位置に配置できます。この入力が与えられた場合:
abc@#d9
a9b#c@d
@@abc#9
abc9d@@
a#b#c@d
正規表現は最初の3行と一致する必要があります。現在、私の正規表現は次のとおりです。
/@.*?#.*?[0-9]/
順番に3つの文字にしか一致しないため、これは機能しません。3つの文字をランダムな順序で一致させる方法は?
本当に使用する必要がある場合は、この醜い正規表現の1つを見つけました。
/(?=.*@)(?=.*#)(?=.*[0-9]).*/
正規表現は基本的に彼らが呼ぶものを使用していますlookahead
http://www.regular-expressions.info/lookaround.html
上記のリンクからの単純なケースは、一致しようとしq
、その後にu
、を実行することです。これが、q(?=u)
と呼ばれる理由であり、その後に先が続くlookahead
ことがわかります。q
u
有効なケースの1つを取り上げましょう。a9b#c@d
最初の先読みは(?=.*@)
、次のように記述されます。すべてに一致し、その後に。が続き@
ます。つまり、文字列ですa9b#c
。先読みからの一致を破棄する必要があるため、エンジンは文字列の先頭である。に戻りますa
。それからそれはに行きます
(?=.*#)
、は次のように述べています。後に続くものすべてに一致すると#
、で検索されa9b
ます。(a)(b)(c)
先読みを使用することと基本的に後退することの違いです。
上記のリンクから:
先読みの意味を確実に理解するために、もう一度内部を見てみましょう。q(?= u)iを適用して終了しましょう。私は先読みをポジティブにし、その後にトークンを置きました。ここでも、qはqと一致し、uはuと一致します。繰り返しますが、先読みからの一致は破棄する必要があるため、エンジンは文字列内のiからuに戻ります。先読みが成功したので、エンジンはiを続行します。しかし、私はあなたに一致することはできません。したがって、この一致の試みは失敗します。文字列にqがないため、残りのすべての試行も失敗します。
維持するのが難しいので醜いです...あなたは基本的にブラケットの中に3つの異なるサブ正規表現を持っています。
別々の式を使用して、@と#が存在することを確認します。それらが終わったら、それらを削除し、残りの文字/数字と一致させます。
私はこれを答えとして書くほうがよいと決めました:
$text = "a9b#c@d";
$themAll = "#@";
$themAny = "0123456789";
echo (strspn($themAll, $text)==strlen($themAll) && strpbrk($text, $themAny));
メンテナンスといくつかの(制限された)拡張については、特にリストが長い場合は、これをできるだけ簡単に拡張できるはず$themAll
です。