8

OK、みんな。これは、このあたりの非常に賢い人々を困惑させたように見えるJavaインタビュータイプの質問です。彼らは実際にプロダクションコードのためにこれを必要としているので、それは単なるインタビューの困惑者以上のものです。

Javaでは、文字列リテラルが3文字の単語NIL以外の場合にtrueを返す正規表現が必要です。テストでは大文字と小文字を区別しない必要があり、RegEx自体がすべての作業を実行する必要があります。

したがって、正規表現はNIL、nil、NiL、nILなどを拒否する必要があります。

ただし、nile、anil、will、zappa-nil-a、および空の文字列を受け入れる必要があります。

些細な正規表現を書くのに何人のJava開発者が必要ですか?どうやらたくさん!

4

2 に答える 2

18

負の先読みを使用してこれを行うことができます。

大文字と小文字を区別しないオプションを有効にした場合:

^(?!nil$).*

.*試合で実際に文字列を返す必要がない場合は、最後にを省略できます。大文字と小文字を区別しないオプションがないバージョンは次のとおりです。

^(?![nN][iI][lL]$).*

説明:

^       # start of string anchor
(?!     # start negative lookahead (fail if...)
   nil    # literal characters 'nil'
   $      # end of string
)       # end lookahead
.*      # consume string (not necessary, but it acts more like a typical regex)

正規表現を一致させたい場合は、先読みの代わりにをnil\n使用します。\z$^(?!nil\z).*

于 2012-04-20T23:26:13.787 に答える
6

これは、文字列の文字を 1 つずつ入力できる有限オートマトンを直接指定する真の正規表現であり、文字列が NIL のバリアントでない場合は受け入れ状態に到達します。

 (|.|..|[^Nn]..|.[^Ii].|..[^Ll]|....+)

これは、ルックアラウンド ハックを実装していない従来の正規表現エンジンで機能し、非常に高速な DFA に変換できます。

これを使用する正規表現関数の種類に応じて、これを^andで固定する必要がある場合があります: (文字列全体) 一致セマンティクス、または部分文字列検索セマンティクス。$

たとえば、grep テスト:

 # rejects lines like nIl and NiL but accepts all else
 # including blank lines:

 grep -E '^(|.|..|[^Nn]..|.[^Ii].|..[^Ll]|....+)$'

ここでの考え方は次のとおりです。

  1. 長さが 1、2、または 4 以上のすべての文字列が一致します。
  2. 次の場合にのみ、3 文字の文字列が一致します。
    1. N または n で始まっていません。また
    2. 真ん中に I または i がありません。また
    3. 末尾に L または l がありません。

NIL と Nil が拒否される理由は、2.1、2.2、および 2.3 の 3 つの規則すべてに違反しているためです。NIL は N で始まるため、2.1 で失敗します。真ん中に I があるので 2.2 に失敗し、最後に L があるので 2.3 に失敗します。

于 2012-04-21T04:12:10.137 に答える