【效率】正则表达式
前言
关于正则相关的基础知识可以在 r2coding 网站中详细查看
正则相关方法可以在 @myzhibie 中查看
本篇文章主要积累在工作中遇到的某些问题或者需求
需求
a.匹配URL中的协议域名端口
文本:http://127.0.0.1:8080/vue/index.html
正则:/(\w+):\/\/([^/:]+)(:\d*)?/
方法:Reg.exec(String)
,通过执行该方法可以得到一个匹配数组,分别为:
完整匹配
子分组1匹配
子分组2匹配
子分组3匹配
…
代码:
1 | const reg = /(\w+):\/\/([^/:]+)(:\d*)?/; |
分析:
/(\w+):\/\/([^/:]+)(:\d*)?/
可以看到该正则有3个分组,整体可匹配到标准URL中的协议、IP、端口(\w+):\/\/
一次或多次匹配://
之前的数字、字母、下划线(即协议)([^/:]+)
一次或多次匹配除了:/
以外的内容(即IP)(:\d*)?
零次或多次匹配:
之后的数字,同时零次或一次匹配整个表达式(即端口可有可无)
b.匹配HTML标签
需求:以 <audio>
标签为例,在一个字符串中筛选出是否携带audio标签
文本:我是开头<audio id="audio-el" autoplay controls></audio>看看能不能截取audio标签
正则:/<audio(\s.+?)*>(.*?)<\/audio>/g
方法:String.match(Reg)
代码:
1 | const reg = /<audio(\s.+?)*>(.*?)<\/audio>/g; |
分析:
/<audio(\s.+?)*>(.*?)<\/audio>/g
全局匹配下执行match()
方法会将所有匹配到的结果在一个数组中全部返回<audio(\s.+?)*>
匹配标签头,标签头中可包含多种属性,因此使用(\s.+?)*
匹配带有空格与任意字符的组零次或多次(.*?)
匹配标签中的内容,除换行符之外的任意字符零次或多次<\/audio>
匹配结束标签
c.替换URL中的双斜杠为单斜杠
需求:防止接口请求拼接URl时导致多出斜杠问题,需要手动将非首个的双斜杠替换为单斜杠
文本:http://127.0.0.1:8080//demo/list
正则:/([^:])(\/\/*)/g
方法:String.replace(reg, string)
将匹配结果替换为指定字符串
代码:
1 | const reg = /([^:])(\/\/*)/g; |
分析:
([^:])
匹配区域首位不是冒号(防止协议处的双斜杠被匹配到)(\/\/*)
2个或2个以上双斜杠replace 方法中的
$1
代表第一个正则匹配到的内容
d.匹配字符串中的Emoji表情
需求:主要用在字符串超长截取时,因Emoji表情在显示时占两个字符,在存储时占四个字节,存在截取出错的问题
文本:😀😁
正则:太长了,看下面代码中吧
方法:Reg.test(String)
匹配该字符串中是否包含Emoji表情
代码:
1 | const reg = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/; |
分析:
该正则由 Kevin Scott 整理
根据不同表情类别进行了区分
建议:因直接截取字符串会存在将Emoji表情错误拆分导致乱码,建议使用 Array.form()
将字符串转化为数组之后,再判断每项是否包含Emoji表情
1 | const reg = /(?:[\u2700-\u27bf]|(?:\ud83c[\udde6-\uddff]){2}|[\ud800-\udbff][\udc00-\udfff]|[\u0023-\u0039]\ufe0f?\u20e3|\u3299|\u3297|\u303d|\u3030|\u24c2|\ud83c[\udd70-\udd71]|\ud83c[\udd7e-\udd7f]|\ud83c\udd8e|\ud83c[\udd91-\udd9a]|\ud83c[\udde6-\uddff]|[\ud83c[\ude01-\ude02]|\ud83c\ude1a|\ud83c\ude2f|[\ud83c[\ude32-\ude3a]|[\ud83c[\ude50-\ude51]|\u203c|\u2049|[\u25aa-\u25ab]|\u25b6|\u25c0|[\u25fb-\u25fe]|\u00a9|\u00ae|\u2122|\u2139|\ud83c\udc04|[\u2600-\u26FF]|\u2b05|\u2b06|\u2b07|\u2b1b|\u2b1c|\u2b50|\u2b55|\u231a|\u231b|\u2328|\u23cf|[\u23e9-\u23f3]|[\u23f8-\u23fa]|\ud83c\udccf|\u2934|\u2935|[\u2190-\u21ff])/; |