我正在寻找一个正则表达式,它将匹配以一个子字符串开头但不以某个子字符串结尾的字符串。
例:
1 2
| // Updated to be correct, thanks @Apocalisp
^foo.*(?<!bar)$ |
应该匹配以" foo"开头但不以" bar"结尾的任何内容。 我知道[^ ...]语法,但是我找不到能对字符串(而不是单个字符)执行此操作的任何东西。
我专门尝试针对Java的正则表达式执行此操作,但是我之前曾遇到过此问题,因此其他正则表达式引擎的答案也将非常有用。
感谢@Kibbee验证了它也可以在C#中运行。
我认为在这种情况下,您需要在后面进行消极检查,如下所示:
通过以下方式验证@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