2012-04-20 49 views
8

好吧,伙计们。这是一个Java面试式的问题,似乎在这里困扰了一些非常聪明的人。他们实际上需要生产代码,所以它不仅仅是一个面试益智游戏。Java正则表达式匹配任何东西但字面上的字符串'NIL'或'零'

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

因此,RegEx应拒绝无,无,NiL,无,等。

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

有多少Java开发人员需要编写一个微不足道的正则表达式?显然很多!

+0

+1这部分斜体在那里,扶手椅Bronco哥们。 – Kaz 2012-04-21 04:15:29

回答

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).*

+0

根据这个问题的主要开发人员之一,你的第一个例子^(?!nil $)。*中的代码将会工作,如果修改如下:“^(?i)(?!nil $)。* Extra因为我们无法控制编译器选项,因此RegEx必须自己完成这项工作 – 2012-04-20 23:38:27

+0

接受这个答案请注意,我们将(?i)添加到RegEx的前面,紧跟在后面“^” – 2012-04-20 23:42:51

+1

@ArmchairBronco'请注意,我们添加了(?i)'是的,这就是为什么Andrew说[启用不区分大小写的匹配](http://www.rexegg.com/regex-modifiers.html#i)。有两种方法可以在Java中执行此操作:'(?i)'和'Pattern.CASE_INSENSITIVE' – zx81 2014-08-08 11:29:20

5

下面是一个真正的正则表达式,它直接指定一个有限自动机,它可以逐个输入字符串的字符,如果字符串不是在NIL变体:

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

这将工作在经典的正则表达式引擎不落实环视黑客,并且可以转换为一个极快的DFA。

您可能需要将其与^$进行关联,具体取决于您使用哪种正则表达式函数:(整个字符串)匹配语义或子字符串搜索语义。

例如,grep的测试:

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

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

这里的想法是:

  1. 长一个,两个或四个或更多的比赛的所有字符串。
  2. 三个字符的字符串匹配当且仅当:
    1. 它不以N或n开头;或
    2. 它没有我或我在中间;或
    3. 它最后没有L或l。

如何NIL和无被拒绝是他们失败的所有三个规则2.1,2.2和2.3。 NIL确实以N开头,所以它失败了2.1。它的中间有一个I,所以它失败了2.2,并且最后确实有一个L,所以失败了2.3。

+0

您可以将它放在您的“主开发人员”管道中,让他抽烟一会儿,哈哈。:) – Kaz 2012-04-21 04:14:21

+0

感谢反馈,Kaz,他不知道他是否抽烟,但我会确保他得到这种新烟草的味道,我赞赏替代方法以及解释。 – 2012-04-22 06:06:28

相关问题