正则表达式之正向后行断言
<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>Real Me真我手机</p>
<p>荣耀手机</p>
</div>
<p><button id="btn" type="button">OK</button> <input id="pipei" type="text" value="(?<=[一-龟])手机" /></p>
<script>
btn.onclick = () => {
let str = mydiv.innerHTML;
str = str.replace(/<\/?span[^>]*>/g,''); //去除 span 标签
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-17 09:43 编辑
三、正向后行断言
(?<=子表达式)表达式
例:
(?<=[一-龟])手机
正则表达式中的后行断言,指子表达式限制其后面将被匹配的主表达式,限制方向属向后限制,所以称为后行断言。
正向后行断言,亦即肯定后行后行断言,引导子表达式的符号为 ?<= ,这个符号可以这么理解以便快速记忆:
? 匹配方向是什么
< 向后
= 等于(肯定,即正向)
上例中的断言子表达式,[一-龟],意为:汉字一至龟所有字中的任意一个,这几乎包括了常用汉字了。[] 用于定义表达式的字符匹配范围,例如之前我们介绍过的 定义的字符匹配范围是 0 到 9 的任意一个数字, 则匹配大小写字母、数字中的任意一个。汉字在编码中也是基本连续存放的,“一”在汉字存放区域放在第一位,GBK汉字放在20902位的是“龥”子,该字不好输入,所以我们改用“龟”字,“龟”放在20896位,差不多囊括完GBK汉字了。
整个子表达式要用圆括号包裹起来,(?<=[一-龟]),意思是如果这个子表达式去匹配的目标字串存在从“一”到“龟”中的任意一个汉字,那么,目标字串就匹配这个子表达式,从而其后面的“手机”主表达式就能匹配。看,匹配子表达式的目的是为了限制主表达式的匹配范围,这就叫断言,它是往子表达式后面的主表达式断言的,所以叫后向断言,子表达式是以肯定形式去匹配(等于一个汉字),所以叫正向后行断言,正向就是肯定的意思。
如一楼所演示,(?<=[一-龟])手机 所能匹配的“手机”,也就是被标红的“手机”,“手机”前面必定是一个汉字,如果是其他的都统统不会标红,因为那样的话就不匹配。如果想匹配“手机”前面是非汉字的,咋办?试下这个表达式:
(?<=[^一-龟])手机
我们加了一个脱字符号 ^,这表示否定方括号里的选择范围,就是,不是汉字。
再试试:
(?<=\w)手机
效果一样。因为,\w 表示的范围是 ,所有字母数字再加一个下划线。
再来试试这个:
(?<=\W)手机
在这里,效果就和 [一-龟] 一样,因为,\W 和 \w 相反,等价于 [^a-zA-Z0-9_],意思是,不是字母数字下划线。
倘若想设定精准一点的后向断言,比方说,我们要去匹配“手机”这个词汇,但它前面只能有两个汉字,那么,请试试:
(?<=^[一-龟]{2})手机
标红的结果会满足我们的设定。子表达式中,脱字符号 ^ 放在第一个方括号的左上角是个边界符号,表示句首,子表达式中的花括号 {2} 是限定前面表达式的匹配数量,也就是,一至龟的汉字中,要出现两个(可以重复,比如“黑黑手机”会被匹配到)。
\W 和 \w 相反,等价于 [^a-zA-Z0-9_],大小写代表的含义相差这么多,真没想到。 \w 表示的范围是 ,之前也是一点不知道。学习了{:4_187:} 加了一个脱字符号 ^,这表示否定方括号里的选择范围。这个时候是不是就是负向的了?
忘记负向是什么样的,我一会再去看看{:4_173:} 红影 发表于 2023-1-17 13:01
加了一个脱字符号 ^,这表示否定方括号里的选择范围。这个时候是不是就是负向的了?
忘记负向是什么样的, ...
不是。这是脱字符号否定选择字符范围的经典用法。^ 有两个意思:
[^0-9] : 否定里面的字符串
^ : 以数字开头的字符串 弄出个图图来看{:4_173:} 马黑黑 发表于 2023-1-17 13:40
不是。这是脱字符号否定选择字符范围的经典用法。^ 有两个意思:
[^0-9] : 否定里面的字符串
哦,放在中括号里面和外面还不一样的呢。 红影 发表于 2023-1-17 16:29
哦,放在中括号里面和外面还不一样的呢。
一个符号,多种用途 樵歌 发表于 2023-1-17 16:02
弄出个图图来看
这个和图无关 马黑黑 发表于 2023-1-17 17:31
一个符号,多种用途
嗯嗯,对了,^的否定和!的否定有什么区别呢?是用的地方不一样? 红影 发表于 2023-1-17 18:59
嗯嗯,对了,^的否定和!的否定有什么区别呢?是用的地方不一样?
在 JS 里,! 表示否定,比如不等于 !=
正则,否定一个字符范围,用 [^ ……] 方式;在断言,也用 !,比如,断言都写在圆括号里: (?!ABC),表示不等于ABC。这些要弄清不容易,除非因需要使用过。 马黑黑 发表于 2023-1-17 19:40
在 JS 里,! 表示否定,比如不等于 !=
正则,否定一个字符范围,用 [^ ……] 方式;在断言,也用 !, ...
这些弄清楚真的不容易呢{:4_187:} 红影 发表于 2023-1-17 21:30
这些弄清楚真的不容易呢
是的,不清楚的时候稀里糊涂,清楚了之后就清清楚楚。 马黑黑 发表于 2023-1-17 22:23
是的,不清楚的时候稀里糊涂,清楚了之后就清清楚楚。
看得多了,慢慢就清楚了{:4_173:} 红影 发表于 2023-1-18 15:51
看得多了,慢慢就清楚了
一般都会这样。
我对JS,很早以前因为需要时看着手册用过一次,后来不再理睬它,再后来有需要用到,又去差手册,弄来弄去基本也就熟悉一点点了 马黑黑 发表于 2023-1-17 17:31
这个和图无关
{:4_203:} 樵歌 发表于 2023-1-18 19:36
{:4_173:} 马黑黑 发表于 2023-1-18 18:26
一般都会这样。
我对JS,很早以前因为需要时看着手册用过一次,后来不再理睬它,再后来有需要用到,又 ...
我是不太有用到JS的需求,不过在黑黑的帖子里,也跟着学到了一些{:4_187:} 红影 发表于 2023-1-18 21:10
我是不太有用到JS的需求,不过在黑黑的帖子里,也跟着学到了一些
做帖子通常会用到,还有做活动,比如上回用到的随机数
页:
[1]
2