正则表达式之环视(?=pattern)(?!pattern)(?<=pattern)(?<!pattern)

环视是指正则表达式引擎先对字符串前后进行环顾观察,再进一步进行匹配操作。环视可分为顺序环视和逆序环视。

环视是不占用宽度的。其含义为:
(性质1)环视所匹配的结果不纳入最终结果,是非捕获匹配
(性质2)环视匹配时匹配指针不会移动

1 顺序环视

顺序环视又称前瞻,即向前查看字符串是否符合相应的条件,若符合才能算当前匹配成功,否则失败。表达式(?=pattern)和(?!pattern)前者表示肯定性前瞻,后者表示否定性前瞻。

1.1(?=pattern)
1.1.1 介绍

(?=pattern)是顺序环视的一种,表示肯定性前瞻,即当前字符串的周围符合pattern时,匹配才算成功。

例如:

String : abc123abc234abcdef
regex  : abc(?=234) 

abc(?=234)表示后边跟着123的abc才算是符合条件,即只有abc123中的abc能匹配成功,abc234和abcdef中的abc都不能匹配成功。

注意:这里是abc123中的abc可以匹配成功,而不是abc123可以匹配成功。

1.1.2 代码实现与验证
  • 验证肯定性前瞻的功能及性质1

给出Java版的实现:

private static void forwardPredicting1(){
    Pattern pattern = Pattern.compile("abc(?=234)");
    Matcher matcher = pattern.matcher("abc123abc234abcdef");
    while (matcher.find()){
        System.out.println(matcher.group());
        System.out.println(matcher.start() + "-----" + matcher.end());
    }
}

运行结果为:

abc
6-----9

从运行结果可以看出只有字符串的索引范围为[6,9)的子串abc被匹配到了,即只有后边跟着123的abc子串符合条件。从运行结果可以看出既符合前瞻的功能也满足环视的性质1。

  • 验证性质2

    private static void forwardPredicting2(){
        Pattern pattern = Pattern.compile("c(?=234)abc");  //只有这行改变
        Matcher matcher = pattern.matcher("abc123abc234abcdef");
        while (matcher.find()){
            System.out.println(matcher.group());
            System.out.println(matcher.start() + "-----" + matcher.end());
        }
    }
    

    运行结果为空。这是因为当引擎扫描到c234的c时,发现c满足前瞻的条件,继续向下扫描,但此时指针指向的是c的下一字符也就是2,发现a与2不匹配则匹配失败。

1.2 (?!pattern)

(?!pattern)是顺序环视的一种,表示否定性前瞻,即当前字符串的周围不符合pattern时,匹配才算成功。因与肯定性前瞻很相似,这里只给出具体验证代码。

private static void forwardPredicting3(){
    Pattern pattern = Pattern.compile("abc(?!234)"); //只有这行改变
    Matcher matcher = pattern.matcher("abc123abc234abcdef");
    while (matcher.find()){
        System.out.println(matcher.group());
        System.out.println(matcher.start() + "-----" + matcher.end());
    }
}

运行结果为:

abc
0-----3
abc
12-----15

可以看出,除了abc234的abc,其余的abc都被匹配到了。

2 逆序环视

逆序环视又称后顾,即向后查看已扫描过的字符串是否符合相应的条件,若符合才能算当前匹配成功,否则失败。表达式(?<=pattern)和(?<!pattern)前者表示肯定性后顾,后者表示否定性后顾。

2.1 (?<=pattern)

给出验证代码:

private static void backwardPredicting1(){
    Pattern pattern = Pattern.compile("(?<=123)abc");
    Matcher matcher = pattern.matcher("abc123abc234abcdef");
    while (matcher.find()){
        System.out.println(matcher.group());
        System.out.println(matcher.start() + "-----" + matcher.end());
    }
}

代码表示只匹配123abc中的abc,所以运行结果为:

abc
6-----9
2.2 (?<!pattern)

给出验证代码:

private static void backwardPredicting2(){
    Pattern pattern = Pattern.compile("(?<!123)abc");
    Matcher matcher = pattern.matcher("abc123abc234abcdef");
    while (matcher.find()){
        System.out.println(matcher.group());
        System.out.println(matcher.start() + "-----" + matcher.end());
    }
}

代码表示只要abc前边不是123的都可以匹配,所以运行结果为:

abc
0-----3
abc
12-----15
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值