阅读数:

js正则表达式之exec和match

0

说明

最近项目中遇到了一个实例,需要将字符串中的特定字符,替代成img标签,即表情以html的方式展示在前端。
数据返回的字符串形如aaaa#E-s01ffff#E-s02ddd#E-s21其中#E-s01为要替换的表情字符,
需要替换为<\img style=”width:25px;height:25px” src=”http://xxx.example.com/im_smart/images/express/base/s21.png" />
该如何做呢?

实现

我们首先想到的肯定是正则表达式,第一步我们要把所有的#E-s01表情字符找出来,抽象成正则表达式就是 #E-s\d{2},这样是能匹配出来,
但是有个问题,在第二步,我们需要将sxx部分动态的拼接在img标签的src属性上,这时候就有点爱莫能助了。那么该怎么办呢,大家都知道
js正则有分组的概念,所有我们将#E-s01分组成 #E-s01(\d{2})即可,为了匹配大小写和全局,最终的表达式为

1
const reg = new RegExp(/#E-s(\d{2})/ig);

接下来就是正则替换了,用string.replace即可;
具体实现如下:

1
2
3
4
5
6
7
8
9
let html = 'aaaa#E-s01ffff#E-s02ddd#E-s21';
const reg = new RegExp(/#E-s(\d{2})/ig);
console.time('match');
let temp = html.match(reg);
temp.forEach((v)=>{
html = html.replace(v,'<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s'+v.replace('#E-s','')+'.png" />')
});
console.log(html)
console.timeEnd('match');

输出结果为:

1
2
3
4
aaaa<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s01.png" />
ffff<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s02.png" />
ddd<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s21.png" />
match: 2.113ms

总共花费了2ms+的时间,实现了我们想要的结果

那么有没有别的实现思路呢?答案肯定是有的,方案一呢我们用到了match函数,将所有的表情字符拿到了,即为一个数组,然后我们循环遍历
用replace加以替换得到结果。除了match还有一种正则方法exec,它俩有啥区别呢,区别就是:

1、当正则表达式无子表达式,并且定义为非全局匹配时,exec和match执行的结果是一样,均返回第一个匹配的字符串内容;

2、当正则表达式无子表达式,并且定义为全局匹配时,exec和match执行,做存在多处匹配内容,则match返回的是多个元素数组;

3、当正则表达式有子表示时,并且定义为非全局匹配,exec和match执行的结果是一样;

4、当正则表达式有子表示时,并且定义为全局匹配,exec和match执行的结果不一样,此时match将忽略子表达式,只查找全匹配正则表达式并返回所有内容;

也就说,exec与全局是否定义无关系,而match则于全局相关联,当定义为非全局,两者执行结果相同

也就是exec此时会返回分组信息,比如#E-s01 可以返回 #E-s 和 01两部分,具体实现如下:

1
2
3
4
5
6
7
8
9
10
let r = "";
const temp = 'aaaa#E-s01ffff#E-s02ddd#E-s21';
const reg = new RegExp(/#E-s(\d{2})/ig);
if(new RegExp(reg).test(temp)){
while(r = reg.exec(temp)) {
temp = temp.replace(r[0],'<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s'+r[1]+'.png" />');
}
}
console.log(temp)
console.timeEnd('exec');

输出结果为:

1
2
3
4
aaaa<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s01.png" />
ffff<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s02.png" />
ddd<img style="width:25px;height:25px" src="http://xxx.example.com/im_smart/images/express/base/s21.png" />
exec: 0.042ms

可以看出结果完全一样,但效率方面,方案二远远胜于方案一

由此也给我们一个启示就是:条条大路通罗马,定有最有解!


^-^欢迎回复交流^-^


0
赏点咖啡钱^.^