web-dev-qa-db-ja.com

一致する正規表現(xではない)とy(!x&y)

パズルが入ったデスクトップの日々のカレンダーを受け取りました。そのようなパズルの1つは、文字が記号に置き換えられた引用を解読することでした。いくつかのRegExを使用して長い単語を検索し、返された単語を使用して小さな単語を解決しました。パズルでは、白い背景記号は母音(「y」を含む)であり、影付きの背景記号は子音でした。

以下ではランダムな文字を使用します。太字は子音を意味し、平易は母音を意味し、斜体は文字が方向に与えられたことを意味します。

[〜#〜] b [〜#〜] O [〜#〜] qq [〜#〜] E

上記の例は、正規表現を使用して「幸せ」(「e」はすでにパズルで与えられています)として解読されました

 egrep -i '^[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]{2}[aiouy]$' words

多くの結果がありましたが、正規表現を論理的に次のように指定することで、正規表現を改善できたと思います。

  1. Char1は子音です
  2. 文字2は母音ですが、指示で与えられたため、「e」ではありません。
  3. 文字3と4は同じ子音ですが、文字1とは異なります。
  4. 文字5は母音ですが、文字2とは異なります。

別の例は

O [〜#〜] r [〜#〜]e[〜#〜] w [〜 #〜] Y [〜#〜] d [〜#〜] On

grepステートメントを使用した場所

egrep -i '^([aiouy])[bcdfghjklmnpqrstvwxz]e[bcdfghjklmnpqrstvwxz][aiouy][bcdfghjklmnpqrstvwxz]\1n$' words

検索を論理的に定義するには

  1. 文字1は母音であり、同じ文字がWordの後半に表示されるため、キャプチャされたグループです。
  2. Char2は子音です。
  3. 文字3は「e」です。
  4. Char4は子音です。
  5. Char5は母音です。
  6. Char6は子音です。
  7. Char7はChar1と同じ母音です。
  8. 文字8は「n」です。

幸い、grepステートメントは「American」という1つの単語を返しました(暗号文は映画の引用でした)。正規表現で、文字4は子音であり、文字2と同じではないことを指定できるようにしたいと思います。文字5は母音であり、文字1と同じではありません。

この種のパターンマッチングをRegExsに依頼することは可能ですか?文字が 'x'または 'である可能性があることを示す(x|y)構文を知っています。 )y 'ですが、(!x) & yを指定する構文が存在する場合はわかりません。

3
user208145

ネガティブな先読みを持つPerl正規表現を使用できます。

$ grep -Pi '^([aeiouy])([bcdfghjklmnpqrstvwxz])e(?!\2)([bcdfghjklmnpqrstvwxz])(?!\1)([aeiouy])(?!\2)(?!\3)([bcdfghjklmnpqrstvwxz])\1n$' /usr/share/dict/words
American
american
everymen

拡張:

$ Perl -lnE '
    BEGIN { $vowel = qr/[aeiouy]/i; $consonant = qr/[bcdfghjklmnpqrstvwxz]/i }
    say if /^ ($vowel)                  # vowel
              ($consonant)              # consonant
              e                         # literal
              (?!\2)($consonant)        # different consonant
              (?!\1)($vowel)            # different vowel
              (?!\2)(?!\3)($consonant)  # 3rd different consonant
              \1                        # first vowel again
              n                         # literal
            $/xi
' /usr/share/dict/words
American
american
everymen

BOQQEの例は次のようになります

grep -Pi '^([bcdfghjklmnpqrstvwxz])([aiouy])(?!\1)([bcdfghjklmnpqrstvwxz])\3(?!\2)([aiouy])$' /usr/share/dict/words

これは私の辞書で779の結果(大文字と小文字を区別する444)を返します。

3
glenn jackman