正则表达式匹配不是特定子字符串的东西

时间:2008-09-04 01:22:59

标签: c# java regex regex-negation

我正在寻找一个匹配字符串的正则表达式,该字符串以一个子字符串开头,并且不以某个子字符串结尾。

示例:

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

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

我特意尝试为Java的正则表达式做这个,但我已经遇到过这个问题,所以其他正则表达式引擎的答案也会很棒。

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

4 个答案:

答案 0 :(得分:9)

我认为在这种情况下你需要负面的背后隐藏,如下所示:

foo.*(?<!bar)

答案 1 :(得分:1)

我不熟悉Java正则表达式,但Pattern Class的文档建议您可以使用(?!X)非捕获零宽度负向前瞻(它寻找不是X的东西)那个postision,没有把它作为反向引用)。所以你可以这样做:

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

更新:Apocalisp是对的,你想要负面的背后隐藏。 (你正在检查。*匹配不会以条形结束)

答案 2 :(得分: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

答案 3 :(得分:0)

正如其他评论者所说,你需要一个消极的前瞻。在Java中,您可以使用以下模式:

"^first_string(?!.?second_string)\\z"
  • ^ - 确保字符串以 first_string
  • \ z - 确保字符串以second_string
  • 结尾
  • (?!。?second_string) - 表示first_string后面不能跟second_string