JS核心知识点梳理——正则篇(上)

正则

image.png

引言

正则是一个前端必须掌握的知识。但是由于用的少,忘了记,记了忘,导致面试经常坐蜡。这里上篇先介绍正则的规则,下篇结合一些具体题目,带大家重新学习巩固一下正则,争取面试给自己加分。

正则是用来处理字符串的一个规则,我们可以利用正则来验证也可以捕获

验证:判断一个字符串是否符合我们的规则-> reg.test(str)
捕获:把字符串中符合我们规矩的子字符捕获到 ->reg.exec(str)

创建正则

实例创建和使用字面量,但是要注意使用实例创建正式是可以使用变量进行拼接的

正则表达式由两种基本字符类型组成,原义文本字符和元字符

元字符:在正则表达式中具有特殊意义的字符,原义字符变元字符加'\'

元字符分类

边界类

^ 开头 $ 结尾 \b 单词边界 \B非单词边界
/\bengineer$/.test('I am an engineer') //true

量词类

*: 零次到多次
+:1次到多次
?: 0次或者1次
{n} 出现n次
{n,m} 出现n次到m次
   let reg = /1\d{10}$/ //验证手机号,第一位是1

字符集类

[a-z] a-z之间的任何一个字符
[a-zA-Z] a-z以及A-Z之间的任何一个字符
1表示非a的所有字符,2 除了xyz以外的任何一个字符
'a1b2C3C4'.replace(/[a-z]/g,'Q') //"Q1Q2C3C4"

预定义类

// .  除了回车和换行的所有字符 [^\r\n]
// \d 数字 [0-9]
//  \s  空白字符 [\t\n\x0B\f\r]
// \w 单词 字符[A-Za-z0-9_]  //注意,.的范围要比\W范围大,因为它还包括制表符之类的`注意只是一个字符而不是一个单词`
'hello'.replace(/\w{2}$/g,'x')  //helx

修饰符以及正则对象属性

修饰符:

i 忽略大小写
g 全局匹配
m 多行匹配
注意这里设置了,在正则对象里的相应属性会改变
var a = /\d/g
a.global  //true
var b = /\d/
b.global  //false

正则对象属性:

global ignore case multiline lastIndex sourse
注意,lastindex在全局匹配里面会匹配一次改变一个,超出匹配范围会被清零
var reg1 = /\w/
var reg2 = /\w/g
reg1.test('a') //true //reg1.lastIndex //0
reg1.test('a') //true //reg1.lastIndex //0
reg1.test('a') //true //reg1.lastIndex //0
reg2.test('a') //true //reg2.lastIndex //1
reg2.test('a') //false //reg2.lastIndex //0
reg2.test('a') //true //reg2.lastIndex //1
reg2.test('a') //false //reg2.lastIndex //0

贪婪模式和非贪婪模式

正则默认是贪婪模式,会按尽可能多的匹配,在量词后面加?可以取消贪婪性

123456.replace(/\d{3,6}/g,'x') //由于有贪婪性,按6次匹配,结果为'x'
'123456'.replace(/\d{3,6}?/g,'x') //此时没有贪婪性,但是有全局匹配,结果为'xx'
'123456'.replace(/\d{3,6}?/g,'x') //此时没有贪婪性,局部匹配,结果为'x456'

分组以及或

或|,左边的单词(分组)或者右边的单词(分组)出现都可以
分组的目的是为了更好的捕获,增加控制力 分组可以用\num代表
在方法中则用$num表示,'bar foo'.replace(/(...) (...)/, '$2 $1')
注意或|的优先级是最低的,比字符串串接的优先级还要小,所以有/Bayron|casper/是匹配两个单词而不是n或者c的情况
所以|多打括号,看一个有括号和括号的区别 匹配010-xxxx 或者 (010)-xxxx 或者xxx这种电话号码
错误:
image
正确:
image


bary{3}  //y重复3次
(bary){3} //单词重复3次
Bayron|casper //两个单词的或   
Bayr(on|ca)sper //中间两个字母随便出现哪个都行,注意同时出现两个是不匹配的
'Bayroncasper'.replace(/Bayr(on|ca)sper/g,'x') //"Bayroncasper"
'Bayrcasper'.replace(/Bayr(on|ca)sper/g,'x')  //"x"

前瞻和后顾

断言表示一个匹配在某些条件下发生,断言不参与匹配
正则匹配的方向是从左向右,所以向右是前瞻(lookahead)或者先行断言
前瞻就是在正则表达式匹配到规则的时候,向前检查是否符合断言,符合断言则匹配生效
正向前瞻是如果匹配的字符后面是什么则生效
就有负向前瞻(Negative lookahead) 负向前瞻指的是如果匹配的字符后面不是什么则生效

'Windows2000'.replace(/Windows(?=2000)/g,'x')  //"x2000" 正向前瞻 ?=
'Windows2001'.replace(/Windows(?!2000)/g,'x')  //"x2001" 负向前瞻 ?!

(正向负向)后顾(lookbehind)则正好与上面说的相反,大家一看例子就懂

'I has Windows2000'.replace(/(?<=I has )Windows/g,'x')  //"I has x2000" 正向后顾 ?<=
'I has Windows2000'.replace(/(?<!He has )Windows/g,'x')  //"I has x2000" 负向后顾 ?<!

还没听懂的同学仔细研究下这个MDN-正则

方法

正则的方法

正则的方法只有两个,test和exec

exec
一个在字符串中执行查找匹配的RegExp方法,它返回一个数组(未匹配到则返回null)。 与字符串的match对应 数组【匹配值,分组,index,input,】
这里注意,exec一次只匹配一个,匹配不到就会null。只有给修饰符g才能往下继续匹配(使用while)
var myRe = new RegExp("d(b+)d", "g");
var myArray = myRe.exec("cdbbdbsbz");
console.log(myArray)
//["dbbd", "bb", index: 1, input: "cdbbdbsbz", groups: undefined]
---------------------------------------------------------------------
var regex1 = RegExp('foo*','g');
var str1 = 'table football, foosball';
var array1;

while ((array1 = regex1.exec(str1)) !== null) {
  console.log(`Found ${array1[0]}. Next starts at ${regex1.lastIndex}.`);
  // expected output: "Found foo. Next starts at 9."
  // expected output: "Found foo. Next starts at 19."
}
test

一个在字符串中测试是否匹配的RegExp方法,它返回true或false。 与字符串的search对应

字符串的方法
search,match

类似test,exec 但是全局调用match相对exec功能弱了一些,返回的数组元素没有index或者input了
match 如果使用g标志,则将返回与完整正则表达式匹配的所有结果,但不会返回捕获组。
如果未使用g标志,则仅返回第一个完整匹配及其相关的捕获组(Array)。 在这种情况下,返回的项目将具有如下所述的其他属性。
使用全局匹配的match

/
var str = 'For more information, see Chapter 3.4.5.1';
var re = /see (chapter \d+(\.\d)*)/i;
var found = str.match(re);

console.log(found);

// logs [ 'see Chapter 3.4.5.1',
//        'Chapter 3.4.5.1',
//        '.1',
//        index: 22,
//        input: 'For more information, see Chapter 3.4.5.1' ]

// 'see Chapter 3.4.5.1' 是整个匹配。
// 'Chapter 3.4.5.1' 被'(chapter \d+(\.\d)*)'捕获。
// '.1' 是被'(\.\d)'捕获的最后一个值。
// 'index' 属性(22) 是整个匹配从零开始的索引。
// 'input' 属性是被解析的原始字符串。
Copy to Clipboard

不使用全局匹配的Match

var str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
var regexp = /[A-E]/gi;
var matches_array = str.match(regexp);

console.log(matches_array);
// ['A', 'B', 'C', 'D', 'E', 'a', 'b', 'c', 'd', 'e']
Copy to Clipboard
split

非常有用的一个方法,用来按规则分解字符串形成数组

'a1b2c3d4'.split(/\d/g)
// ['a','b','c','d']
replace

非常非常有用的一个方法,全局匹配下由于能自动不断匹配,非常方便。
注意如果参数是字符串会隐式转换为

'a1b1'.replace('1','x') // axb1   为什么会只替换一次呢,因为这里会给你隐式的转换为正则表达式
'a1b1'.replace(/1/g,'x') // axbx
'a1b1'.replace(/\d/g,function(match){ //匹配字符串,分组(没有则没有该参数),index,原字符
    return ~~match + 1
}) // a2b2

  1. a
  2. xyz

前端小羊羊
爱健身,爱编码,爱生活,欢迎小妹妹来撩我
1.3k 声望
658 粉丝
0 条评论
推荐阅读
vue3简易实现——响应式原理
1.前言之前听有人吐槽,说面试让实现一个简易vue3。咱们先不说这题离不离谱,简单分析下,如果遇到了该怎么思考。首先vue分为以下几个部分响应系统渲染器(mount,patch,domdiff)组件化编译器编译器不可能写出来...

Runningfyy阅读 841

ESlint + Stylelint + VSCode自动格式化代码(2023)
安装插件 ESLint,然后 File -&gt; Preference-&gt; Settings(如果装了中文插件包应该是 文件 -&gt; 选项 -&gt; 设置),搜索 eslint,点击 Edit in setting.json

谭光志34阅读 20.9k评论 9

安全地在前后端之间传输数据 - 「3」真的安全吗?
在「2」注册和登录示例中,我们通过非对称加密算法实现了浏览器和 Web 服务器之间的安全传输。看起来一切都很美好,但是危险就在哪里,有些人发现了,有些人嗅到了,更多人却浑然不知。就像是给门上了把好锁,还...

边城32阅读 7.4k评论 5

封面图
涨姿势了,有意思的气泡 Loading 效果
今日,群友提问,如何实现这么一个 Loading 效果:这个确实有点意思,但是这是 CSS 能够完成的?没错,这个效果中的核心气泡效果,其实借助 CSS 中的滤镜,能够比较轻松的实现,就是所需的元素可能多点。参考我们...

chokcoco24阅读 2.3k评论 3

在前端使用 JS 进行分类汇总
最近遇到一些同学在问 JS 中进行数据统计的问题。虽然数据统计一般会在数据库中进行,但是后端遇到需要使用程序来进行统计的情况也非常多。.NET 就为了对内存数据和数据库数据进行统一地数据处理,发明了 LINQ (L...

边城17阅读 2.1k

封面图
过滤/筛选树节点
又是树,是我跟树杠上了吗?—— 不,是树的问题太多了!🔗 相关文章推荐:使用递归遍历并转换树形数据(以 TypeScript 为例)从列表生成树 (JavaScript/TypeScript) 过滤和筛选是一个意思,都是 filter。对于列表来...

边城18阅读 7.9k评论 3

封面图
Vue2 导出excel
2020-07-15更新 excel导出安装 {代码...} src文件夹下新建一个libs文件夹,新建一个excel.js {代码...} vue页面中使用 {代码...} ===========================以下为早期的文章今天在开发的过程中需要做一个Vue的...

原谅我一生不羁放歌搞文艺14阅读 20.1k评论 9

1.3k 声望
658 粉丝
宣传栏