正则表达式以匹配非特定子字符串的内容
时间:2020-03-05 18:47:25 来源:igfitidea点击:
我正在寻找一个正则表达式,它将匹配以一个子字符串开头但不以某个子字符串结尾的字符串。
例子:
// Updated to be correct, thanks @Apocalisp ^foo.*(?<!bar)$
应该匹配以" foo"开头但不以" bar"结尾的任何内容。我知道[^ ...]语法,但是我找不到能对字符串(而不是单个字符)执行此操作的任何东西。
我专门尝试为Java的正则表达式执行此操作,但是我之前曾遇到过此问题,因此其他正则表达式引擎的答案也将非常有用。
感谢@Kibbee验证它在Cas中是否可以正常工作。
解决方案
回答
我不熟悉Java正则表达式,但是Pattern类的文档建议我们可以使用(?!X)进行非捕获的零宽度负前瞻(它在该姿势下查找不是X的东西,而不捕获它)作为反向参考)。因此,我们可以执行以下操作:
foo.*(?!bar) // not correct
更新:Apocalisp的权利,我们想向后看。 (我们正在检查。*匹配的内容是否以bar结尾)
回答
正如其他评论者所说,我们需要提前否定。在Java中,我们可以使用以下模式:
"^first_string(?!.?second_string)\z"
- ^-确保字符串以first_string开头
- \ z-确保字符串以second_string结尾
- (?!。?second_string)-表示first_string后不能跟second_string
回答
我认为在这种情况下,我们想在后面进行否定检查,例如:
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