距离上次更新已有5年之久,本着生命不息,学习不止的态度,
今天趁着大家顶着7月的烈日炎炎出去团建,而我在公司吹着免费空调、喝着老板请的星爸爸、摸着鱼…
打开沉封已久的博客,随便更新点东西
今天不讲新技术,不说新轮子。随便扒一扒百家通用的基础 正则
学习任何技术最好的线上教科书莫过于官方文档,这里附上链接,大家自行翻阅
土味介绍
为什么说正则
是百家通,如果你接触过任何一门语言,无论哪一种,不出意外都会用到正则,
你会发现它他们语法都差不多,正则就像一个小弟,需要依赖不同宿主的环境。
所以,你如果从一种语言环境切换到别一个种言环境中使用正则
,你只需学习下这种语言调用正则
的函数方法即可。
正则的应用场景
最多的应用场景 就是字符串的增删改查
,可能这里有人说,前端不是已经有很多处理一些字符串的方法了吗?说的没错,但正则
的方式要更强悍些。这种感觉就好像过去的老人机
与智能机
的对比。
话不闲扯,开始上干货……
正菜上来前,先举个简单的甜品小🌰 来区别对比传统方式
和正则
需求:从一堆字符串中全局找数字
1 | var str ='linjie20210716'; |
🌰 现开始从浅入深 一样一样上主菜
🌰1:字面量。
- 🌰设一个需求:让正则在一堆字符串里找
小姐姐
1 | var str ='xiaojiejie20210716'; |
🌰2:用对象创建正则表达式
1 |
|
🌰3:选择符 |
类似于 js语法中的或
||
- 🌰设一个需求:判断一个电话号码是不是北京或上海
1 | var str ='010-12345678'; |
*** 土味语义:^
代指开始, $
表示结束,是边界的限定, 010或021 为了简洁这里用()
学名原子组
的东西括起来,-
和d
在正则有特殊意义故需要用\
转义,{7-8}属于区间匹配
代表数字7到8位` ***
有人说🙋♀️ :那如果我们匹配很多数字的时候不是很麻烦,不是要(1|2|3|4|5|6|7|8|9|0)
,
这里就要提到正则的一个概念叫 原子表
[]
代表一个可选范围
[1234567890] 相当于 (1|2|3|4|5|6|7|8|9|0)
继续简化 -
中线符 指定范围区间
[0-9] 就相当于[0123456789]
同样的区别匹配还有[a-z][A-Z]
,要注意的是这里顺序不像模式参数/gi
,它不可颠倒成[z-a][9-0]
区分:
1 | 'xiaojiejie'.match(/ie/g);//=>["ie", "ie"]全量匹配ji为整体 |
即然提到原子组
也顺带讲下原子组
- 🌰设一个需求:匹配一个日期 中间可以是”-“中线,也可以是”/“,条件是前后一至,若前一个用中线,后面必须跟中间。不可以是
2021-07/16
1 | var date = "2021-07-16" |
土味语义: 关建节点在([-\/])
原子组 代表包含 了”-“中线或
”/“两种形式,由于其中/是特殊字面量,需用’'转义,\1代表这里要求与第一个原子组的规则结果相同
- 🌰现在我们来实现一个需求:
**将下面代码中的h1-h6标签中的 内容全部替换成空字符 **
1 | var str='<div><h1>linjie.fe.com xiaojiejie</h1><h2>xiaojiejie2</h2><h3>xiaojiejie3</h3><H4></H4><h6>xiaojiejie666</h6></div>' |
***土味语义: 以 <
开始 (h[1-6])
原子组中代只h1-h6 [\s\S]*
表示空白加非空白所有字符 零个至多个字符 <\/\1>
代表 </h1>-</h6>
/\1
代表与第一个原子组规则相同 ***
🌰3.1 原子组引用完成替换操作
🌰设需求: 将所有
<h1>
至<h6>
标签 替换为<p>
标签。介绍两种方法:上代码:
1 | var str=`<h1>小姐姐1</h1><span>小姐姐2</span><h6>小姐姐6</h6>`; |
🌰3.2 嵌套分组和不记录组 ?:
当不记录组的时候 正则中不记录原子组的内容 也不会打印,这时候 ‘$1’或‘$2’ 也不会找到对应序列号
这里有个需求匹配url 让正则只记录域名部分
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16var str = `http://www.baidu.com
https://www.nodejs.org`;
var reg = /https?:\/\/((\w+\.)?\w+.(com|cn|org))/i; //这是记录全部的情况
console.dir(str.match(reg)); //=> [0: "http://www.baidu.com", s1: "www.baidu.com", 2: "www." 3: "com"]
//step2 忽略掉www.和.com
var reg1 = /https?:\/\/((?:\w+\.)?\w+.(?:com|cn|org))/gi;//[0: "http://www.baidu.com",1: "www.baidu.com"]
console.dir(reg1.exec(str));
while((res=reg1.exec(str))){
console.dir(res[1]);//=> www.baidu.com www.nodejs.org
}***土味语义: 着重讲下上例中有三个
?
第一个?
代表有或没有s; 第二、三个?
代表后面的字面量不记录到组编号
当中 ***
🌰4:特殊字面量的转义
- 🌰设一个需求: 用正则匹配一个url地址
1 | var url = 'https://linjieFE.github.io'; |
***土味语义:^ $
开始结束边界的限定, ?
代码0或1次术语上又属于一种称为禁止贪婪
的语法,禁止贪婪
有趋向于最少数的性质,后面我会再次讲到。也可理解为没有
或有的时候只能有一个
(https://) \w
代表 字母大小写数字下划线 相当于 [A-Za-z0-9_]
+
学名也叫 贪婪匹配
代表一个或多个字母大小写数字下划线 ***
注意
上面的字面量内容如果放在正则表达式对象
里 情况则不同
字面量/^(https:\/\/)?\w+\.\w+\.\w+$/
,单个反斜杠会自行转义
但如果在 new RegExp("(https:\/\/)?\w+\.\w+\.\w+,'g')
中,于由第一个参数本身为数符串,正常使用则要改为new RegExp("(https:\\/\\/)?\\w+\\.\\w+\\.\\w+",'g')
4.1 禁止贪婪
禁止贪婪
有趋向于最少数的性质
1 | 'xjjjjjj'.match(/xj+?/);//=>"xj" '+'是{1,} 所以禁止贪婪后取一个字母j |
🌰5: 字符边界的约束 ^$[]{}
这个前面已代过了 直接到🌰6
🌰6: 数字空白元字符 \s
匹配空白包括 相当于 [\n\f\r\t\v]
1 | var url = ' 小姐姐:021-1234556, linjie:010-1234556 '; |
排除匹配
土味语义: 全局匹配出一个或多个 除
中线、数字、冒号、逗号 的字符
^
在 [] 原子表
里面 代表取返[^]
,术语称其为排除匹配
, 这里要特别注意跟 区间符
中的’开始’^
区分开.
- 另需注意
- 当原子组和原子表中使用特殊符号时没有换算关系,仅代表其中的字符本义,(所以转不转义也无妨)举例:
1 | '(xiaojiejie).+'.match(/[()]/g);//=>["(", ")"] 这里 “原子表" 里包括了个“ 原子组” 实际上,原子表代表的只有字符串括号 |
🌰7:在元字符里除了^
,还有另一种特殊取反的方式
P如:
\d 代表数字 \D 代表 除数字
\w 代表数字字母下划线 \W 代表 除代表数字字母下划线
相同的还有 \s \S 等等…\s
代三空格、换行、等同与[\n\r]
- 🌰设一个需求:匹配一个电话号码,中间两边允许存在0-1个空字符.如:’010 - 1234567’
1 | '010 - 1234567'.match(/^\d+\s?\-\s?\d{7,8}$/); |
土味语义: \d+
贪婪匹配一个或多个数字 \s?``有一个
或没有
空字符 ,\-
中线 最后\d{7-8}
精准匹配7-8位数字 $
结束
.
贪婪的点 代表除 换行符
以外所有的字符
🌰7 更加贪婪的全字符
我们知道 哪怕最贪婪的.+
也排除了一个换行符
🌰设一个需求:匹配一段代码标签内的所有内容
可以用双向取反的方式 例如:[\s\S] [\w\W]
1 | var str =`<span> |
🌰8 正则的修正符i
g
‘s’
修正符一般用在正则表达示的结尾
- 🌰设一个需求:我们匹配xiaoJiejie中的
j
1 | 'xiaoJiejie'.match(/j/gi);//=>Jj |
土味语义: /gi
这里结尾中的i
带代不分大小写,g
代表全局 否则这里只会匹配一个就会跳出,这里/gi
同样可以写成 /ig
*** /s
是忽略换行符 当文档出来换行符时,将其看作一行 ***
🌰9 多行匹配
- 🌰业务要求:将str中包含在两个
#
号之间的数据过滤为[{name:'成都小姐姐',age:'18'}]
数组对象格式
1 | // step1 |
土味语义step1: /gm
这里结尾中的m
代表每一行分别处理,\s*
开始空白符有
或没有
都可,这里有有泛指 1 个到多个,#
号 \d+
一个或多个数字,\s+
一个或多个空白符 .+
除换行符所有字符 \s+
一个或多个空白符 #
号结束
土味语义step2: 先把开头部分替换,空白符 1 个到多个,#
号 \d+
一个或多个数字,\s*
零个或多个空白符 替换为空字符串;再将结尾部分空折符到#号结属部分替换为空字符串
后面的步骤不用多讲了,就是简单的解构 return对象
🌰10 字符属性 汉字 和 宽字节
在正则里字符串有自己的属性值prototype,比如{L}
代表着字母属性
1 | 'xjj1'.match(/\p{L}/gu)//=>["x", "j", "j"] |
*土味语义: \p
代码匹配属性是否为字母{L}
,/gu
全局 这里注意匹配属性必段要带/u
,带特别是用来试别宽字节
时, 例如匹配一些罗码字符时*
🌰10 lastindex
🌰11 有效率的/y模式
🌰12 $
符 在正则中的使用
- 🌰设一个需求将
(010)12212333 (021)13390000
改为010-12212333 021-13390000
- 上代码
1
2
3
4
5
6
7
8
9var str =`(010)12212333 (021)13390000`;
//step1 把区号和号码用原子组组起来
var reg =/\((\d{3,4})\)(\d{7,8})/
//step1 先匹配一次来看 这里找到 原子组 $1 和 $2 位置
str.match(reg);//=> [0: "(010)12212333", 1: "010", 2: "12212333"]
//step3 加上全局现在组起来
var reg1 =/\((\d{3,4})\)(\d{7,8})/g
str.replace(reg1,'$1-$2')//=>"010-12212333 021-13390000"
$``代表自身前面字符
$’代指自身前面字符
$&`代指字符自身,相当于$0
1 |
|
- 🌰设一个业务场景
- 将”…使用正则,你只需学习当前语言调用正则的函数方法即可…”这句话中带有
正则
字样的字符都加上http://linjieFE.github.io
的连接
1 |
|
原子组别名
的应用场景
- 🌰设一个业务场景,将
str
中所以连接和名称放在一个数组中[{link:'',name:''}]
1 | var str=`<div><a id='lj' href="http://www.baidu.com">百度</a><a href="http://www.qq.com">腾讯</a><a href="http://www.jd.com">JD</a></div>` |
*** 土味语义:原子组别名?<link>
, ·
一个空格 href前有或没有内容并禁止贪婪
,href=””这里可能是单引号也可能是双引号,所以 用(["'])
,(.*?)
为连接内容; \1
与(["'])
同,/i
不区别大小写 ***
🌰13 断言匹配
相当于正则中的条件语句
🌰设一个业务场景 将”…使用正则表达式,你只需学习当前语言调用正则的函数方法即可…” 中后面的带有
表达示
字样正则
字符串 加上http://linjieFE.github.io
的链接
1 |
|
*** 土味语义:?=
代指向后匹配条件的 ?!
代指 后面不满足条件的 ?<
代指向前匹配条件的 ?<!
前非 代指零负宽向后匹配条件的 ***
- 🌰1业务场景 内容前后都不能出现’小姐姐’字样
1 | //.* 代表零个或多个 |
<待更。。。>
敲码不易,请多多赞赏!
- 本文作者: 林杰
- 本文链接: http://linjiefe.github.io/2021/07/16/关于正则/