2

[更新了答案]

  1. 不以“hede”开头:^(?!hede).*$
  2. 包含“hede”:^((?!hede).)*$
  3. 不以“hede”结尾:(?s)^.*+(?<!hede)$

所有 3 个表达式都有效。

检查:

Pattern p = Pattern.compile("(?s)^.*+(?<!hede)$");
assertTrue( p.matcher("hede obsolete").matches()); //ok 
assertTrue( p.matcher("obsolete hede obsolete").matches()); //ok
assertFalse(p.matcher("obsolete hede").matches()); //ok
4

3 回答 3

3

你可以使用lookbehind它。

^.*(?<!hede)$

或者你可以使用

^.*+(?<!hede)$

使用@stribizhev建议的所有格量词

于 2015-10-19T09:46:31.460 回答
3

关于@vks 建议的解决方案的一些话^.*(?<!hede)$:在一种情况下会很好 - 使用所有格量词.*, .*+。更新后的正则表达式将如下所示:

(?s)^.*+(?<!hede)$
       ^

此外,inline 修饰符(?s)可用于强制 a.匹配换行符,这样我们也可以检查多行字符串是否以 . 结尾hede

加号有很大的不同。由于每次测试字符时,前面(?<!hede)带有模式的后视都会检查是否存在,所以这个正则表达式不太稳定。所有格量词将确保在整个字符串/行匹配后不会发生回溯,并且只有在它之后才执行 1 次缺席检查。.*hedehede

作为替代方案,您可以在开头使用否定前瞻来检查字符串是否以结尾hede(此版本可以与 一起使用matcher.find):

(?s)^(?!.*hede$)

或者,匹配不以 结尾的整行/字符串hede

(?s)^(?!.*hede$).*

正则表达式演示

IDEONE demo,例如matches()(没有$结尾,因为整个字符串必须匹配):

System.out.println("A string with hede".matches("(?s)^(?!.*hede$).*")); // => false
System.out.println("A string without".matches("(?s)^(?!.*hede$).*")); // => true
于 2015-10-19T09:48:39.153 回答
2

您可以使用此负前瞻

^(?!.*hede$).*$

正则表达式演示

于 2015-10-19T09:48:34.030 回答