正则表达式匹配不是特定子字符串的内容
Posted
技术标签:
【中文标题】正则表达式匹配不是特定子字符串的内容【英文标题】:Regex to match against something that is not a specific substring 【发布时间】:2010-09-07 18:20:57 【问题描述】:我正在寻找一个正则表达式,它将匹配以一个子字符串开头且不以某个子字符串结尾的字符串。
例子:
// Updated to be correct, thanks @Apocalisp
^foo.*(?<!bar)$
应匹配以“foo”开头且不以“bar”结尾的任何内容。我知道 [^...] 语法,但我找不到任何可以为字符串而不是单个字符执行此操作的内容。
我专门尝试为 Java 的正则表达式执行此操作,但我之前遇到过此问题,因此其他正则表达式引擎的答案也会很棒。
感谢@Kibbee 验证这在 C# 中也有效。
【问题讨论】:
正如我在下面提到的 - 输入字符串“foo123bar”的正则表达式将匹配“foo12” - 希望这是理想的行为。 【参考方案1】:我不熟悉 Java 正则表达式,但 Pattern Class 的文档建议您可以使用 (?!X) 进行非捕获零宽度负前瞻(它在该位置寻找不是 X 的东西,而不将其捕获为反向引用)。所以你可以这样做:
foo.*(?!bar) // not correct
更新:Apocalisp 是对的,你想要消极的后视。 (您正在检查 .* 匹配的内容是否以 bar 结尾)
【讨论】:
此解决方案的问题在于,对于输入字符串“foo123bar”,它将匹配“foo12” - 希望这是所需的行为。【参考方案2】:使用以下方法验证了@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】:我认为在这种情况下你想要消极的后视,就像这样:
foo.*(?<!bar)
【讨论】:
【参考方案4】:正如其他评论者所说,您需要消极的前瞻性。在 Java 中,您可以使用这种模式:
"^first_string(?!.?second_string)\\z"
^ - 确保字符串以
first_string
\z - 确保字符串以 second_string 结尾
(?!.?second_string) - 表示first_string后面不能跟second_string
【讨论】:
以上是关于正则表达式匹配不是特定子字符串的内容的主要内容,如果未能解决你的问题,请参考以下文章