如果所需字符串前面直接包含某个字符,则正则表达式不匹配

10

我正在尝试解决此CodingBat问题

如果给定的字符串中包含“xyz”的出现,其中xyz没有直接前置句点(.)则返回true。因此,“xxyz”计数,但“x.xyz”不计数。

xyzThere("abcxyz") → true
xyzThere("abc.xyz") → false
xyzThere("xyz.abc") → true

我正在尝试使用正则表达式解决此问题,但我不确定如何处理“xyz没有直接前缀句点”的要求。

没有限制条件的问题的解决方案是:

public boolean xyzThere(String str) {
    return str.matches(".*xyz.*");
}

有什么办法可以用正则表达式处理这个限制条件吗?


"Negative lookbehind"是你要寻找的正则表达式功能。但是为了使用它,你还需要了解它的限制。你可以在这里了解更多信息:http://www.regular-expressions.info/lookaround.html#lookbehind 和 http://www.regular-expressions.info/lookaround.html#limitbehind。 - Pshemo
2个回答

13
一个否定字符类应该能解决问题:str.matches(".*(?:^|[^.])xyz.*") 这里我们使用一个非捕获组(?:^|[^.])来确保我们匹配字符串的开始位置^,或者任何不是句点的位置[^.]

8

我个人使用了这种解决方案,但还有许多其他变体:

str.matches("(.*[^.])?xyz.*")

我只需确保xyz前面没有任何内容,然后句号.就不会直接出现在它前面。
您也可以编写一个反向查找的解决方案:
str.matches(".*(?<!\\.)xyz.*");

(?<! ) 部分是负向预测先行断言,\\.(字面上的句号)是我们要检查的模式。


@KelvinMackay:Java中的matches默认使用锚点。 - nhahtdh
我已经通过了CodingBat上的测试用例。请提供一个无法通过代码的测试用例。 - nhahtdh
@KelvinMackay:问题是我写的正则表达式与在String类中的matches方法中使用^$的版本等效。如果没有假定锚点,你的论点就是正确的。 - nhahtdh
我明白,但这不是我尝试时它不起作用的原因。无论如何,这不重要 - 它在CodingBat上运行,所以你的答案是正确的 :) - Kelvin
哦,没意识到Coding Bat有导入的限制,知道了很好 :) - Woot4Moo
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接