综合技术

系统认识JavaScript正则表达式

微信扫一扫,分享到朋友圈

系统认识JavaScript正则表达式
0

一、正则表达式简介

1、什么是正则表达式

正则表达式,又称规则表达式。(英语:Regular Expression,在代码中常简写为regex、regexp或RE),计算机科学的一个概念。正则表达式通常被用来检索、替换那些符合某个模式(规则)的文本。

简单的说,就是按照某种规则去匹配符合条件的字符串。

2、可视化正则表达式工具

Regexper: https://regexper.com/

二、RegExp对象

实例化 RegExp
的两种方式。

两种方式定义RegExp对象。

1、字面量

let reg = /[a-z]{3}/gmi;
let reg = /[a-z]{3}/g;
let reg = /[a-z]{3}/m;
let reg = /[a-z]{3}/i;

标志

g
m
i

2、构造函数

let reg = new RegExp('\bis\b', 'g');

因为JavaScript字符串中
属于特殊字符,需要转义。

很多时候跟着书和网站查找资料学习,会发现没有目标,学了很多却不知道自己到底能够做出什么成绩。要有一个清晰的职业学习规划,学习过程中会遇到很多问题,你可以到我们的前端学习交流q-u-n【 784783012 】,基础,进阶。从企业招聘人才需求 到怎么学习前端开发,和学习什么内容都有免费系统分享,让你无论是自学还是找相应的培训都能让你少走弯路。希望可以帮助你快速了解前端,学习前端

三、元字符

把元字符当作转义字符。

正则表达式有两种基本字符类型组成。

  • 原义文本字符
  • 元字符

1、原义文本字符

表示原本意义上是什么字符,就是什么字符。

2、元字符

是在正则表达式中有特殊含义的非字母字符。

* + ? $ ^ . | ( ) { } [ ]

字符含义
t水平制表符
v垂直制表符
n换行符
r回车符
空字符
f换页符
cX控制字符,与X对应的控制字符(Ctrl + X)

类似于转义字符。

四、字符类

表示符合某种特性的字符类别。

使用元字符 []
可以构建一个简单的类。

所谓类是指符合某些特性的对象,一个泛指,而不是某个字符。

例子

表达式 [abc]
把字符 a
b
c
归为一类,表达式可以匹配这一类中的任意一个字符。

// replace() 方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。
'a1b2c3d4e5'.replace(/[abc]/g, '0');  //010203d4e5

字符类取反

我们想要替换不是 abc
中任意一个字符的字符。

// 元字符 ^ 创建一个 反向类/负向类
'abcdefg'.replace(/[^abc]/g, '0');  //abc0000

五、范围类

匹配这一个范围内的字符。

如果我们想要匹配数字 0-9
,那么我们可能会这样写 [0123456789]

如果我们想要匹配 26
个字母,那么我们可能会这样写 [abcdefghijklmnopqrstuvwxyz]

这样略显麻烦,所以才会有范围类。

例子

// 替换所有数字
'a1c2d3e4f5'.replace(/[0-9]/g, 'x');  //axcxdxexfx
// 替换所有小写字母
'a1c2d3e4f5'.replace(/[a-z]/g, 'x');  //x1x2x3x4x5
// []组成的类内部是可以连写的。替换所有大小写字母
'a1C2d3E4f5G6'.replace(/[a-zA-Z]/g, '*');  //*1*2*3*4*5*6

疑问

如果我想替换数字,并且连带 -
符号也一起替换呢?

// 替换所有数字和横杠
'2018-5-21'.replace(/[0-9-]/g, '*');  //*********

六、预定义类

一些已经定义的类,可以直接使用。

字符等价类含义
. [^rn]除了回车、换行之外的所有字符
d [0-9]数字字符
D [^0-9]非数字字符
s [tnx0Br]空白符
S [^tnx0Br]非空白符
w [a-zA-Z_0-9]单词字符(字母、数字、下划线)
W [^a-zA-Z_0-9]非单词字符

例子

替换一个 ab
+ 数字
+ 任意字符
的字符串

// 写法1
'ab0c'.replace(/ab[0-9][^rn]/g, 'TangJinJian');  //TangJianJian
// 写法2
'ab0c'.replace(/abd./g, 'TangJinJian');  //TangJianJian

七、单词边界

字符含义
^以xxx开始(不在中括号内时的含义)
$以xxx结束
b单词边界
B非单词边界

例子

我想替换的字符串,属于那种只在开头出现的。

'YuYan is a boy, YuYan'.replace(/^YuYan/g, 'TangJinJian');  //TangJinJian is a boy, YuYan

我想替换的字符串,属于那种只在结尾出现的。

'YuYan is a boy, YuYan'.replace(/YuYan$/g, 'TangJinJian');  //YuYan is a boy, TangJinJian

单词边界例子。

// 替换所有is为0
'This is a man'.replace(/is/g, '0');  //Th0 0 a man
// 替换所有is前面带有单词边界的字符串
'This is a man'.replace(/bis/g, '0');  //This 0 a man
// 替换所有is前面没有单词边界的字符串
'This is a man'.replace(/Bisb/g, '0');  //Th0 is a man

八、量词

用来处理连续出现的字符串。

字符含义
?出现零次或一次(最多出现一次)
+出现一次或多次(至少出现一次)
*出现零次或多次(任意次)
{n}出现n次
{n,m}出现n到m次
{n,}至少出现n次

我想替换字符串中连续出现 10
次的数字为 *

'1234567890abcd'.replace(/d{10}/, '*');  //*abcd

我想替换字符串中的QQ号码。

'我的QQ是:10000'.replace(/[1-9][0-9]{4,}/, '19216811');  //我的QQ是:19216811

九、贪婪模式

尽可能多的匹配。

有这样的一种场景下的正则表达式, /d{3,6}/
该替换3个数字还是6个数字呢,4、5个数字?

// 贪婪模式会尽可能的往多的方面去匹配
'123456789'.replace(/d{3,6}/, 'x');  //x789
'123456789'.replace(/d+/, 'x');  //x
'123456789'.replace(/d{3,}/, 'x');  //x

十、非贪婪模式

尽可能少的匹配。

如果我们想要最低限度的替换呢?

// 非贪婪模式使用 ? 尽可能的往少的方面去匹配
'12345678'.replace(/d{3,6}?/g, 'x');  //xx78
'123456789'.replace(/d{3,6}?/g, 'x');  //xxx

因为有 g
标志,会匹配这段字符串里所有符合规则的字符串。

第一个规则 /d{3,6}?/g
12345678
中有两个符合条件的字符串,是 123
456
。所以替换结果是 xx78

第二个规则 /d{3,6}?/g
123456789
中有三个符合条件的字符串,是 123
456
789
。所以替换结果是 xxx

十一、分组

括号里的一些规则,分为一组。

我想替换连续出现3次的 字母
数字

//没有分组的情况下,后面的量词,只是表示匹配3次数字。
'a1b2d3c4'.replace(/[a-z]d{3}/g, '*');  //a1b2d3c4
//有分组的情况下,分组后面的量词,表示符合这个分组里规则的字符串,匹配3次。
'a1b2d3c4'.replace(/([a-z]d){3}/g, '*');  //*c4

1、或

分组里有两种规则,只要满足其中一种即可匹配。

//我想把ijaxxy和ijcdxy都替换成*
'ijabxyijcdxy'.replace(/ij(ab|cd)xy/g, '*');  //**

2、反向引用

可以把分组视为变量,来引用。

//我想把改变年月日之间的分隔符
'2018-5-22'.replace(/(d{4})-(d{1,2})-(d{1,2})/g, '$1/$2/$3');  //2018/5/22
//我想替换日期,并且更改顺序
'2018-5-22'.replace(/(d{4})-(d{1,2})-(d{1,2})/g, '$2/$3/$1');  //5/22/2018

3、忽略分组

忽略掉分组,不捕获分组,只需要在分组内加上 ?:

// 忽略掉匹配年的分组后,匹配月的分组变成了$1,日的分组变成了$2
'2018-5-22'.replace(/(?:d{4})-(d{1,2})-(d{1,2})/g, '$1/$2/$3');  //5/22/$3

十二、前瞻

正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”。

前瞻就是在正在表达式匹配到规则的时候,向前检查是否符合断言,后顾/后瞻方向相反。

JavaScript不支持后顾。

符合和不符合特定断言称为 肯定/正向
匹配和 否定/负向
匹配。

名称正则含义
正向前瞻 exp(?=assert)
负向前瞻 exp(?!assert)
正向后顾 exp(?<=assert)JavaScript不支持
负向后顾 exp(?<!assert)JavaScript不支持

例子

有这样一个 单词字符
+ 数字
格式的字符串,只要满足这种格式,就把其中的单词字符替换掉。

'a1b2ccdde3'.replace(/w(?=d)/g, '*');  //*1*2ccdd*3

有这样一个 单词字符
+ 非数字
格式的字符串,只要满足这种格式,就把前面的单词字符替换掉。

'a1b2ccdde3'.replace(/w(?!d)/g, '*');  //a*b*****e*

十三、RegExp对象属性

global
是否全文搜索,默认 false

ignore case
是否大小写敏感,默认是 false

multiline
多行搜索,默认值是 false

lastIndex
是当前表达式匹配内容的最后一个字符的下一个位置。

source
正则表达式的文本字符串。

let reg1 = /w/;
let reg2 = /w/gim;

reg1.global;  //false
reg1.ignoreCase;  //false
reg1.multiline;  //false

reg2.global;  //true
reg2.ignoreCase;  //true
reg2.multiline;  //true

十四、RegExp对象方法

1、RegExp.prototype.test()

用来查看正则表达式与指定的字符串是否匹配。返回 true
false

let reg1 = /w/;
reg1.test('a');  //true
reg1.test('*');  //false

加上 g
标志之后,会有些区别。

let reg1 = /w/g;
// 第一遍
reg1.test('ab');  //true
// 第二遍
reg1.test('ab');  //true
// 第三遍
reg1.test('ab');  //false
// 第四遍
reg1.test('ab');  //true
// 第五遍
reg1.test('ab');  //true
// 第六遍
reg1.test('ab');  //false

实际上这是因为 RegExp.lastIndex
。每次匹配到之后, lasgIndex
会改变。

lastIndex
是正则表达式的一个可读可写的整型属性,用来指定下一次匹配的起始索引。

let reg = /w/g;
// 每次匹配到,就会把lastIndex指向匹配到的字符串后一个字符的索引。
while(reg.test('ab')) {
    console.log(reg.lastIndex);
}
// 1
// 2

reg.lastIndex
初始时为 0
,第一个次匹配到 a
的时候, reg.lastIndex
1
。第二次匹配到 b
的时候, reg.lastIndex
2

展开阅读全文

Building AI in your company (week 3)

上一篇

Comparing past and present Unreal Engine 4 animation compression

下一篇

你也可能喜欢

评论已经被关闭。

插入图片
系统认识JavaScript正则表达式

长按储存图像,分享给朋友