马黑黑 发表于 2023-1-18 09:27

正则表达式之负向后行断言

<style>
#mydiv { #with: 600px; }
#mydiv >p { margin: 10px 0; padding: 0; }
</style>

<h2>负向后行断言</h2>
<div id="mydiv">
        <p>一加手机</p>
        <p>一加one plus手机</p>
        <p>小米手机</p>
        <p>小米_手机</p>
        <p>华为手机</p>
        <p>OPPO手机</p>
        <p>vivo手机</p>
        <p>Real Me手机</p>
        <p>荣耀手机</p>
</div>
<p><button id="btn" type="button">Okey</button> <input id="pipei" type="text" value="(?<!)手机"/></p>

<script>

btn.onclick = () => {
        let str = mydiv.innerHTML;
        str = str.replace(/<\/?span[^>]*>/g,'');
        let reg = new RegExp(pipei.value.trim(), 'g');
        let ar = str.match(reg);
        if (ar) {
                mydiv.innerHTML = str.replace(reg,'<span style="color: red">$&</span>');
        }
}

</script>

马黑黑 发表于 2023-1-18 09:28

本帖最后由 马黑黑 于 2023-1-18 09:30 编辑

四、负向后行断言

(?<!子表达式)表达式

例:

(?<!)手机

子表达式的引导符号是 ?<! ,与正向后行断言的 ?<= 相比就是把等号 = 变为了感叹号 ! ,属否定性质的断言,用以限制后面主表达式的匹配范围。这种断言称“负向后行断言”或“否定后行断言”。上面的例子,(?<!)手机,用意是我们不想匹配 OPPO 和 vivo 手机,子表达式 (?<!) 表示,在子表达式所在位置,目标字符串不能是 o 或 O ,即 中的任意一个都不能是,若此,就匹配后面的“手机”字符串。运行结果,除 OPPO手机 和 vivo手机 外,其余的都匹配标红。

断言中的负向,或称否定,要通过引导符号 ?<! 引出子表达式,用“子表达式不等于什么什么”来限定该位置之后的主表达式是否匹配,正如上面的例子所示,待检测字串在子表达式的位置上的字眼,如果不是 o 或 O,那么,其后的“手机”就匹配。

请注意,断言匹配目的是匹配子表达式前面或后面的主表达式,匹配结果不包含子表达式,所以,以下正则表达式,虽然也以否定形式进行匹配,但表达式没有主次之分,且匹配结果会连同否定表达式在目标检索对象所在位置一同给出,不属于断言匹配:

[^oO]手机

这个非断言匹配的正则表达式表示,如果“手机”前面的字符不是 o 也不是 O,那么就匹配。匹配的结果将是:

一加手机 → 加手机

“加”匹配了 [^oO],“手机”匹配表达式中的 手机 。

而使用断言匹配,子表达式对应的位置是一加手机中的“加”,但“加”不作为匹配结果,所以匹配的是“一加手机”中的“手机”。

至此,四种断言正则表达式都介绍完了,希望感兴趣的朋友能够慢慢理解。断言是正则表达式的高级应用,是很多行内人都望而却步的东东,要理解它不容易,要熟练使用它更不容易。

红影 发表于 2023-1-18 13:45

谢谢黑黑,将四种断言正则表达式都仔细地介绍了一遍,辛苦了{:4_187:}

红影 发表于 2023-1-18 13:48

讲得非常仔细,黑黑辛苦了{:4_190:}

樵歌 发表于 2023-1-18 18:18

别尽说虚的,给俺一部实实在在的华为瘦鸡如何{:4_173:}

马黑黑 发表于 2023-1-18 18:19

樵歌 发表于 2023-1-18 18:18
别尽说虚的,给俺一部实实在在的华为瘦鸡如何

木有

樵歌 发表于 2023-1-18 19:57

马黑黑 发表于 2023-1-18 18:19
木有

抠门儿{:4_173:}

马黑黑 发表于 2023-1-18 20:30

樵歌 发表于 2023-1-18 19:57
抠门儿

华为缺芯
页: [1]
查看完整版本: 正则表达式之负向后行断言