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

例子:

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

应匹配以“foo”开头且不以“bar”结尾的任何内容。我知道 [^...] 语法,但我找不到任何可以对字符串而不是单个字符执行此操作的内容。

我专门尝试为 Java 的正则表达式执行此操作,但我之前遇到过此问题,因此其他正则表达式引擎的答案也很棒。

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

有帮助吗?

解决方案

我想在这种情况下你想要 消极回顾, ,像这样:

foo.*(?<!bar)

其他提示

使用以下方式验证@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

我不熟悉 Java 正则表达式,但不熟悉 模式类 建议您可以使用 (?!X) 进行非捕获零宽度负前瞻(它在该位置查找不是 X 的内容,而不将其捕获为反向引用)。所以你可以这样做:

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

更新: :Apocalisp 是对的,你想要消极的后视。(您正在检查 .* 匹配的内容是否不以 bar 结尾)

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

"^first_string(?!.?second_string)\\z"
  • ^ - 确保字符串以first_string开头
  • \z - 确保字符串以 secondary_string 结尾
  • (?!.?second_string) - 表示first_string 后面不能跟第二个_string
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top