Java RegEx匹配任何内容但是文字字符串'NIL'或'nil'

时间:2012-04-20 23:23:17

标签: java regex null

好的,伙计们。这是一个Java面试类型的问题,似乎让一些非常聪明的人在这里难倒。他们实际上需要这个用于生产代码,因此它不仅仅是一个采访益智游戏。

他们需要一个Java中的正则表达式,如果字符串文字是任何而不是3个字母的单词NIL,则返回true。测试需要不区分大小写,RegEx本身必须完成所有工作。

因此,RegEx应拒绝 NIL,nil,NiL,nIL,等。

然而,它应该接受:nile,anil,will,zappa-nil-a和空字符串。

编写一个简单的RegEx需要多少Java开发人员?显然很多!

2 个答案:

答案 0 :(得分:18)

您可以使用negative lookahead

执行此操作

启用不区分大小写的选项:

^(?!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).*

答案 1 :(得分:5)

这是一个真正的正则表达式,直接指定一个有限的自动机,可以逐个输入字符串的字符,如果字符串不是NIL的变体,将达到接受状态:

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

这适用于没有实现环视黑客攻击的经典正则表达式引擎,可以转换为超快的DFA。

您可能必须使用^$来锚定它,具体取决于您使用的正则函数类型:(整个字符串)匹配语义或子字符串搜索语义。

例如,grep test:

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

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

这里的想法是:

  1. 所有长度为一,二或四或更多的字符串匹配。
  2. 当且仅当以下情况时,三个字符的字符串匹配:
    1. 它不是以N或n开头;或
    2. 中间没有I或i;或
    3. 最后没有L或l。
  3. 如何拒绝NIL和Nil是因为它们都失败了所有三个规则2.1,2.2和2.3。 NIL确实以N开头,因此它失败了2.1。它确实有一个I在中间,所以它失败了2.2,它最后有一个L,所以它失败了2.3。