正则在JS中的应用——看看能不能看得懂
本帖最后由 马黑黑 于 2022-3-25 20:25 编辑 <br /><br /><p>先看效果:<br><br><div id="ttBox" style="border: 1px solid;padding: 10px;">
<p>单击改变部分前景色:<br><br><div id="ttBox" style='border: 1px solid; width: 300px; padding: 10px;'></p>
</div>
<script>
var flag = true;
var ttBox = document.getElementById("ttBox");
var str = ttBox.innerHTML;
ttBox.onclick = function() {
if(flag){
var pattern = /(["'])([^"']{1,})(["'])/gm;
str = str.replace(pattern, "<span style='color: magenta;'>$1$2$3</span>");
this.innerHTML = str;
}
flag = false;
}
</script>
本帖最后由 马黑黑 于 2022-3-25 20:31 编辑
一楼,单击有边框的盒子,部分文本的颜色会改变。所以,我们得现有一个 div 之类的盒子:
<div id="ttBox" style="border: 1px solid; width: 600px; padding: 10px;">
<p>单击改变部分前景色:<br><br><div id="ttBox" style='border: 1px solid; width: 300px; padding: 10px;'></p>
</div>这个div盒子预设了一些文字,我们的目标是,单击盒子后,小角双引号和单引号及其里面的文字要变成红紫色,这个需要用JS来操作,且得用上正则表达式。正则表达式非常难以理解,之前我们灌水时谈论过,试看代码:
<script>
var flag = true;
var ttBox = document.getElementById("ttBox");
var str = ttBox.innerHTML;
ttBox.onclick = function() {
if(flag){
var pattern = /(["'])([^"']{1,})(["'])/gm;
str = str.replace(pattern, "<span style='color: magenta;'>$1$2$3</span>");
this.innerHTML = str;
}
flag = false;
}
</script>
代码量不大,可是,有谁看得懂吗?
本帖最后由 马黑黑 于 2022-3-25 21:20 编辑
JS解释:
02行:var flag = true;
11行:flag = false;
这是声明一个布尔变量,它的作用是只允许第一次单击操作有效,避免无限演变下去。开始时,flag 为真,到了第一一行,即运行完毕,它变为假了,早单击窗体也没用了。
03、04行:
var ttBox = document.getElementById("ttBox"); //获得盒子操作句柄
var str = ttBox.innerHTML; //获得盒子里的超文本
05、12行:窗体单击操作的匿名函数主体
ttBox.onclick = function() {
// ......
}
然后就是非常核心和难懂的了:
如果 flag 值为真,那么——
07行:var pattern = /(["'])([^"']{1,})(["'])/gm;
这是构建正则表达式,并赋值给变量 pattern。表达式主体用符号 / / 包围起来,就是说,/ / 告诉浏览器,我里面是正则表达式。后面的 gm,g是全局变量,m是多行变量,gm合起来的意思是说,我这个正则表达式是全部要查找的、且支持多行的。
正则表达式主体分三组,各组放在小角括号内:(["'])([^"']{1,})(["'])
第一组:(["'),把括号去掉,就是 ["'],方括号表示里面字符 " 和 ' 中的任意一个只要出现一次;
第二组:([^"']{1,}),去掉括号是 [^"']{1,},前边方括号部分是 [^"'],^ 在这里是否定词,意思是说,只要不是 " 和 ' 中的任意一个,后面部分是 {1,},出现一次或多次;
第三组:(["']),这和第一组的意思是一样的,是小角双引号或单引号的收尾。
三组内容合起来,全部意思是:如果一个字串存在由小角双引号或单引号中的一个起头一次、接着只要不是小角双引号或单引号,不管出现多少次、然后是小角双引号或单引号收尾一次,则这样的字符串就是“我”要创建的字符串规则。
08行:str = str.replace(pattern, "<span style='color: magenta;'>$1$2$3</span>");
第八行用 JS 的 replace 内置函数按已创建的正则表达式替换盒子里的字符串为所需要的样式。replace 需要两个参数:
string.replace(替换字符或规则, 替换成什么);
替换规则就是我们前面创建的正则表达式 pattern 变量,这是 replace 的参数一。参数二是构建的CSS新样式加引号内的文本:首先是CSS的style行内样式,这个应该看得懂;其次是 $1$2$3,$1表示正则表达式规则中分组的第一组,$2是第二组,$3是第三组。引号内的内容各不相同,所以这个 $x 是核心,是模糊二智能替换的关键,但它不难,知道了就可以直接用来拼接新字串。
09行:this.innerHTML = str;
第九行简单,把替换后新的字符串变量 str 重写到 div 盒子中。
小结:难度最大的是正则表达式的构建,它要能准确描述小角括号及其里面的文本规则,并分若干组以便 replace 替换时精准到位,达到模糊匹配、精准替换的目的。其次是替换成什么的描述,也属于正则范畴,关键的东东是 $x,x 对应于分组索引。还有,replace() 函数是个新知识点,这是替换函数,它以字符对字符的替换只替换第一个匹配的字串,且不能模糊匹配,而使用正则,可以通过开关 g 全局匹配与替换,通过 m 开关可以多行匹配与替换。
没看懂{:4_173:} 红影 发表于 2022-3-25 20:33
没看懂
应该看不懂。这个比较烧脑的 马黑黑 发表于 2022-3-25 20:37
应该看不懂。这个比较烧脑的
这个虽然不熟悉,但逻辑很清晰。黑黑辛苦了{:4_187:} 红影 发表于 2022-3-25 22:28
这个虽然不熟悉,但逻辑很清晰。黑黑辛苦了
如果有延续,那么,正则还是可以接受的,因为之前的确介绍过正则 马黑黑 发表于 2022-3-25 22:34
如果有延续,那么,正则还是可以接受的,因为之前的确介绍过正则
是的,那会就觉得这个挺厉害。不过苦于实在不熟悉,没怎么记住{:4_173:} 红影 发表于 2022-3-25 22:43
是的,那会就觉得这个挺厉害。不过苦于实在不熟悉,没怎么记住
先知道个大概吧,然后如果有需要再一点一点熟悉。它的用处很大的,例如,在文档流中模糊查找,所有模糊匹配的都标注颜色,或是底色或是前景色,这就用上正则。 马黑黑 发表于 2022-3-25 22:48
先知道个大概吧,然后如果有需要再一点一点熟悉。它的用处很大的,例如,在文档流中模糊查找,所有模糊匹 ...
嗯,充分利用了计算机的运算功能{:4_187:} 红影 发表于 2022-3-25 22:58
嗯,充分利用了计算机的运算功能
正则对于计算机的运算,根本算不上什么 马黑黑 发表于 2022-3-25 23:43
正则对于计算机的运算,根本算不上什么
嗯,它的运算能力实在是太强大了。 红影 发表于 2022-3-26 13:11
嗯,它的运算能力实在是太强大了。
但是老是弄得一头雾水,一天前前编写测试好的正则式子就看大半天才看懂{:5_106:} 马黑黑 发表于 2022-3-26 13:43
但是老是弄得一头雾水,一天前前编写测试好的正则式子就看大半天才看懂
自己写的还得半天才懂啊,这个正则式子的确太难了点{:4_173:} 红影 发表于 2022-3-26 15:30
自己写的还得半天才懂啊,这个正则式子的确太难了点
有时候进入不了角色,一下子转不过弯来 马黑黑 发表于 2022-3-26 16:30
有时候进入不了角色,一下子转不过弯来
转不过弯,这说法很有趣{:4_173:} 红影 发表于 2022-3-26 20:16
转不过弯,这说法很有趣
人人可能都会存在一时转不过弯来的思维现象 马黑黑 发表于 2022-3-26 20:27
人人可能都会存在一时转不过弯来的思维现象
别人有可能,那么聪明的你也会转不过弯啊{:4_173:} 红影 发表于 2022-3-26 21:37
别人有可能,那么聪明的你也会转不过弯啊
老了呗,都一百来岁了 马黑黑 发表于 2022-3-26 22:17
老了呗,都一百来岁了
哈哈,扣除个零还差不多{:4_173:}