2008-09-04 97 views
16

我正在寻找一个正则表达式,它将匹配以一个子串开头并且不以特定子串结尾的字符串。正则表达式来匹配不是特定子串的东西

例子:

// Updated to be correct, thanks @Apocalisp 
^foo.*(?<!bar)$ 

应该匹配任何以 “foo” 的开头,并且不能与 “酒吧” 结束。我知道[^ ...]语法,但是我找不到任何能够为字符串而不是单个字符做的事情。

我特意试图为Java的正则表达式做这件事,但我已经遇到过,所以其他正则表达式引擎的答案也会很好。

感谢@Kibbee验证这是否也适用于C#。

+0

正如我下面提到 - 正则表达式中输入字符串问题 “foo123bar” 它将匹配“foo12” - 希望这是理想的行为。 – Dmitry 2015-12-23 22:44:38

回答

9

我认为在这种情况下,你想负回顾后,像这样:

foo.*(?<!bar) 
1

我对Java正则表达式不熟悉,但Pattern Class的文档建议您可以使用(?!X)作为非捕获零宽度负向预测(它在该事件中寻找不是X的东西,而不是将其作为反向引用)。所以,你可以这样做:

foo.*(?!bar) // not correct 

更新:Apocalisp的权利,你要负回顾后。 (你正在检查什么。*匹配不会以bar结尾)

+0

这个解决方案的问题在于,对于输入字符串“foo123bar”它将匹配“foo12” - 希望这是期望的行为。 – Dmitry 2015-12-23 22:43:51

0

正如其他评论者所说,你需要一个负面预测。在Java中,你可以使用这个模式:

"^first_string(?!.?second_string)\\z" 
  • ^- 确保字符串 first_string
  • \ Z开始 - 手段 - 确保字符串second_string
  • 结束(second_string?!?)这first_string不能跟着second_string
1
使用

验证@ Apocalisp的回答是:

import java.util.regex.Pattern; 
public class Test { 
    public static void main(String[] args) { 
    Pattern p = Pattern.compile("^foo.*(?<!bar)$"); 
    System.out.println(p.matcher("foobar").matches()); 
    System.out.println(p.matcher("fooBLAHbar").matches()); 
    System.out.println(p.matcher("1foo").matches()); 
    System.out.println(p.matcher("fooBLAH-ar").matches()); 
    System.out.println(p.matcher("foo").matches()); 
    System.out.println(p.matcher("foobaz").matches()); 
    } 
} 

此输出正确的答案:

false 
false 
false 
true 
true 
true