关于c#:Regex以匹配非特定子字符串的内容

关于c#:Regex以匹配非特定子字符串的内容

Regex to match against something that is not a specific substring

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

例:

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

应该匹配以" foo"开头但不以" bar"结尾的任何内容。 我知道[^ ...]语法,但是我找不到能对字符串(而不是单个字符)执行此操作的任何东西。

我专门尝试针对Java的正则表达式执行此操作,但是我之前曾遇到过此问题,因此其他正则表达式引擎的答案也将非常有用。

感谢@Kibbee验证了它也可以在C#中运行。


我认为在这种情况下,您需要在后面进行消极检查,如下所示:

1
foo.*(?<!bar)

通过以下方式验证@Apocalisp的答案:

1
2
3
4
5
6
7
8
9
10
11
12
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());
  }
}

输出正确的答案:

1
2
3
4
5
6
false
false
false
true
true
true


我对Java正则表达式不熟悉,但是Pattern类的文档建议您可以使用(?!X)进行非捕获的零宽度负超前(在该姿势下查找不是X的东西,而不捕获它)作为反向引用)。因此,您可以执行以下操作:

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

更新:Apocalisp的权利,您想向后看。 (您正在检查。*匹配的内容是否以bar结尾)


正如其他评论者所说,您需要提前否定。在Java中,您可以使用以下模式:

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


推荐阅读