23-正则表达式

本文详细介绍了正则表达式的基本概念、创建方法、字符分类、模式修饰符、实例方法如exec和test的用法,以及正则表达式在JavaScript中的应用,包括String对象的search、match、split和replace方法。同时,涵盖了正则表达式的元字符、数量词、边界符、字符类等重要概念,解析了贪婪和非贪婪模式,以及选择、分组和引用的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

正则表达式

1. 什么是正则表达式?

  • 正则表达式是由一个字符序列形成的搜索模式。

  • 当你在文本中搜索数据时,你可以用搜索模式来描述你要查询的内容。

  • 正则表达式可以是一个简单的字符,或一个更复杂的模式。

  • 正则表达式可用于所有文本搜索和文本替换的操作。

2. 正则表达式的创建

2.1 字面量
// 在一对反斜线中写正则表达式内容,如/abc/
// 正则表达式里面不需要加引号 不管是数字型还是字符串型
var reg = /正则表达式/修饰符;
var reg = /hello/g;
2.2 构造函数
//构造正则表达式的实例,如new RexExp('abc')
//内部传入的参数为字符串/字符串的变量
var reg =new RegExp("正则表达式","修饰符")
var reg =new RegExp("hello","g");

3. 字符分类

3.1 普通字符

字母、数字、下划线、汉字、没有特殊含义的符号(,;!@等)

3.2 特殊字符

\:将特殊字符转义成普通字符

3.3 模式修饰符
  • i:ignoreCase,匹配时忽视大小写
  • m:multiline,多行匹配
  • g:global,全局匹配

字面量创建正则时,模式修饰符写在一对反斜线后

4. 正则表达式实例方法

4.1 exec
匹配到返回值是一个result数组:[匹配的内容,index: 在str中匹配的起始位置,input: 参数字符串,groups: undefined] 否则返回null
var str = 'hello123 world hello javascript';
// 字面量
// 如果没有设置一个全局模式  每次都会回到索引0的位置重新查找
var reg = /hello/g;
// exec匹配成功返回一个数组   失败则会返回null
console.log(reg.lastIndex);  //0
console.log(reg.exec(str));  //[ 'hello',index: 0,input: 'hello123 world hello javascript',groups: undefined ]
console.log(reg.exec(str));  //[ 'hello',index: 15,input: 'hello123 world hello javascript',groups: undefined ]
console.log(reg.lastIndex);  //20

// 利用循环查看每次exec校验之后的结果
while (true){
    var result = reg.exec(str);
    // 何时终止这个循环
    if(!result){
        break;
    }
    console.log(result[0],result['index']);  //hello 0  hello 15
}

注意点:

  1. 如果正则表达式中有修饰符"g",这时,在正则表达式的实例reg中会维护lastIndex属性,记录下一次开始的位置,当第二次执行exec的时候,从lastIndex开始检索。
  2. 如果正则表达式中没有修饰符"g",不会维护lastIndex属性,每次执行从开始位置检索
4.2 test

用来测试待检测的字符串中是否有可以匹配到正则表达式的字符串,如果有返回true,否则返回false

// test匹配成功  返回true   失败返回false
var str = 'hello123 world hello javascript';
var reg = /hello/g;
console.log(reg.test(str));  //true

注意点:

  1. 如果正则表达式中有修饰符"g",这时,在reg中会维护lastIndex属性,记录下一次开始的位置,当第二次执行test的时候,从lastIndex开始检索。
  2. 如果正则表达式中没有修饰符"g",不会维护lastIndex属性,每次执行从开始位置检索
4.3 toString/toLocaleString
// toString  toLocaleString  返回 /hello/ 字符串
var str = 'hello123 world hello javascript';
var reg = /hello/g;
console.log(reg.toString(str));  //  /hello/g
console.log(reg.toLocaleString(str));  //  /hello/g
4.4 valueOf
// 返回正则表达式本身
var str = 'hello123 world hello javascript';
var reg = /hello/g;
console.log(reg.valueOf());  //  /hello/g

5 正则表达式实例属性

5.1 lastIndex

当没设置全局匹配时,该属性值始终为0。每次正则查找的起点就是lastIndex。

// lastIndex  如果没有开启全局匹配模式  始终为0  每次校验都会从开始位置重新校验
// 如果开启了全局模式  每次校验都会记录当前满足条件的字符的位置  下次校验从这个位置开始
var str = 'hello hello hello';
var reg1 = /hello/;
var reg2 = /hello/g;
// 没有开启全局模式的
console.log(reg1.lastIndex);  //0
console.log(reg1.exec(str));  //[ 'hello',index: 0,input: 'hello hello hello',groups: undefined ]
console.log(reg1.lastIndex);  //0

// 开启全局模式的
var str = 'hello hello hello';
var reg1 = /hello/;
var reg2 = /hello/g;
console.log(reg2.lastIndex);  //0
console.log(reg2.exec(str));  //返回第一个hello
console.log(reg2.lastIndex);  //0

console.log(reg2.lastIndex);  //0
console.log(reg2.exec(str));  //返回第一个hello
console.log(reg2.lastIndex);  //5

console.log(reg2.lastIndex);  //5
console.log(reg2.exec(str));  //返回第二个hello
console.log(reg2.lastIndex);  //11

console.log(reg2.lastIndex);  //11 
console.log(reg2.exec(str));  //返回第三个hello
console.log(reg2.lastIndex);  //17

console.log(reg2.lastIndex);  //返回null
console.log(reg2.exec(str));  //0
console.log(reg2.lastIndex);  //返回第一个hello
5.2 ignoreCase、global、multiline

判断正则表达式中是否有忽略大小写、全局匹配、多行匹配三个模式修饰符

// ignoreCase、global、multiline
var reg3 = /hello/igm;
console.log(reg3.ignoreCase); //true
console.log(reg3.global); //true
console.log(reg3.multiline);  //true
5.3 source

返回字面量形式的正则表达式

// source   类似于toString
var reg4 = /hello/igm;
// console.log(reg4.source); //hello

6. 正则表达式语法-元字符

6.1 直接量字符
字符匹配
字母和数字字符自身
\oNull字符
\t制表符
\n换行符
\v垂直制表符
\f换页符
\r回车符
//直接量字符
var str = 'hello \nworld hello javascript';
var reg = /\n/;
console.log(reg.test(str));  //true
console.log(reg.exec(str));  //[ '\n',index: 6,input: 'hello \nworld hello javascript',groups: undefined ]
6.2 字符集合
  • [abc] 查找方括号之间的任何字符
  • [0-9] 查找任何从0至9的数字
  • [^xyz] 一个反义或补充字符集,也叫反义字符组。也就是说,它匹配任意不在括号内的字符。你也可以通过使用连字符 ‘-’ 指定一个范围内的字符。反义字符要和方括号一起使用。
var str = 'asd qwe zxc rty';
// 匹配的是一个整体   abc 
var reg = /asd/;
// 使用字符集合  只要有其中的一个字符 就会满足校验条件
var reg2 = /[awe]/;
// console.log(reg2.exec(str));  //[ 'a', index: 0, input: 'asd qwe zxc rty', groups: undefined ]

// 做一个区间的值的选择  [0-9]  [a-z]  [A-Z]
var str = 'asd1 qwe2 zxc3 rty';
var reg1 = /[0-9]/;
var reg2 = /[a-z]/;
var reg3 = /[A-Z]/;
console.log(reg1.exec(str));  //[ '1', index: 3, input: 'asd1 qwe2 zxc3 rty', groups: undefined ]
console.log(reg2.exec(str));  //[ 'a', index: 0, input: 'asd1 qwe2 zxc3 rty', groups: undefined ]
console.log(reg3.exec(str));  //null

// [^]  [^0-9] 除了0-9之间的数字其他字符都可以 
// [a-z] 
//  [A-Z]
var str = 'asd1 qwe2 zxc3 rty';
var reg = /[^asd]/;
console.log(reg.exec(str));  //[ '1', index: 3, input: 'asd1 qwe2 zxc3 rty', groups: undefined ] 
// \d  ->  [0-9]

注意:^写在[]里面是补充字符集
var str = 'abc qwe abd1,2'
console.log(str);
var reg1 = /[^abc ]/igm;
console.log(reg1.exec(str)); //true

7. 边界符

^ 匹配输入开始;

$ 匹配输入结尾。

^和 $ 在一起,表示必须是精确匹配。

// ^  以什么开头  以谁结束
// 写在方括号内 代表取反
// var reg = /[^0-9]/;
// 写在方括号外  以谁结束
var reg = /^[0-9]/;
// console.log(reg.test('qweqwe'));
// $  以什么开头  以谁结束
var reg2 = /[a-z]$/
// console.log(reg2.test('qweqwe'));

// ^ $一起使用  精确匹配
var reg3 = /^abc$/;
// console.log(reg3.test('abc qwe abc'));   //false
// console.log(reg3.test('abc'));   //true
var reg4 = /^[abc]$/;
console.log(reg4.test('a'));

\b 匹配一个零宽单词边界(zero-width word boundary),表示一个单词(而非字符)边界,也就是单词和空格之间的位置,或者字符(\w)与字符串开头或者结尾之间的位置。

\B 匹配一个零宽非单词边界(zero-width non-word boundary),与"\b"相反。

var str = 'Hello World Hello JavaScript';
var reg1 = /\bHello\b/g;
var reg2 = /\BScrip\B/g;
console.log(reg1.exec(str));
console.log(reg2.exec(str));

8. 字符类

字符类含义
.匹配除换行符\n和回车符之外的任何单个字符,等效于**[^\n\r]**
\d匹配一个数字字符,等效于[0-9]
\D[^0-9]
\w匹配包括下划线的任何单个字符,包括AZ,az,0~9和下划线**""**,等效于[a-zA-Z0-9]
\W[^a-zA-Z0-9_]
\s匹配任何Unicode空白字符,包括空格、制表符、换页符等,等效于[\f\t\n\r]
\S[^\f\t\n\r]

“.” 除换行符\n和回车符之外的任何单个字符

\d 匹配一个数字字符,等效于[0-9]

\D 等效于**[^0-9]**

\w匹配包括下划线的任何单个字符,包括AZ,az,0~9和下划线**""**,等效于[a-zA-Z0-9]

\W [^a-zA-Z0-9_]

\s 匹配任何Unicode空白字符,包括空格、制表符、换页符等,等效于[\f\t\n\r]

\S 等效于**[^\f\t\n\r]**

// . 除了\n和\r之外  全部都可以匹配
var reg = /./;
console.log(reg.exec('\nasd123'));


var str = 'hello world hello javascript';
//  \d  ->  [0-9]
var reg = /^\d/;
console.log(reg.test(str));
//  \D  ->  [^0-9]
var reg2 = /^\D/;
console.log(reg2.test(str));


var str = 'hello world hello javascript';
//  \w  ->  [a-zA-Z0-9_]
var reg = /^\w/;
console.log(reg.test(str));
//  \W  ->  [^a-zA-Z0-9_]
var reg2 = /^\W/;
console.log(reg2.test(str));


// 以空白字符开头
var str = '\nHello World Hello 123JavaScript';
var reg1 = /^\s/g;
console.log(reg1.exec(str));
// 不以空白字符开头
var str = 'Hello World Hello 123JavaScript';
var reg1 = /^\S/g;
console.log(reg1.exec(str));

9. 数量词

字符含义
*>=0次
+≥1 次
0或1次
{n}n 次
{n,}≥n 次
{n,m}n到m 次

X* 匹配前面的模式 x -> 0 或多次。等价于{0,}

X+ 匹配前面的模式 x -> 1 或多次。等价于 {1,}。

X? 匹配前面的模式 x -> 0 或 1 次。等价于{0,1}

X{n} n为非负整数。前面的模式 x 重复出现 n 次时匹配

X{n,} n为非负整数。前面的模式 x 重复出现至少 n 次时匹配。

X{n,m} n和m为非负整数。前面的模式 x 重复出现至少 n 次,至多 m 次时匹配。

// *  允许出现0次或一次
var reg = /^a*$/;
console.log(reg.test('aaa'));

//  +允许一次或多次
var reg2 = /^a+$/;
console.log(reg2.test('aaaaaa'));

//  ?允许0次或多次
var reg2 = /^a?$/;
console.log(reg2.test('a'));

// {n}  固定重复n次
var reg = /^a{3}$/;
// var reg = /^\d{3}$/;  =  var reg = /^a{3}$/;
// 只要满足字符是0-9之间的字符  就可以连续编写为16  不需要重复
console.log(reg.test('aaa'));

// {n,}大于等于n次
var reg2 = /\d{3,}/;
console.log(reg2.test('012'));

// {n,m}大于等于n次  小于等于m次
var reg3 = /^\d{3,6}$/;
console.log(reg3.test('012012012012'));

10. 案例

  1. 匹配QQ号
  2. 匹配身份证号
  3. 匹配11位有效手机号码
// 1.不能以数字0开始,只能由数字组成,长度为5-11位
var regQQ = /^[1-9]\d{4,10}$/;
console.log(regQQ.test('123123123')); //true

// 2.不能以数字0开头,只能由数字组成,最后一位可能是x,X,数字
var regID = /^[1-9]\d{16}[xX\d]$/;
console.log(regID.test('123123123123123323'));  //true

// 3.以1为开头  第二位为3,4,5,7,8中的任意一位  最后以0-9的9个整数结尾 
var regPhone = /^1[3,4,5,7,8]\d{9}$/;
console.log(regPhone.test('18822473596'));  //true

11. 重复方式

11.1 贪婪模式

​ 尽可能多的匹配(首先取最多可匹配的数量为一组进行匹配),当匹配剩余的字符串,还会继续尝试新的匹配,直到匹配不到为止,为默认模式。

// 对字符串"123456789",匹配其中的数字3-6次:\d{3,6},先匹配数字出现6次的字符串(123456),然后再从剩余字符串(789)中匹配出现数字3次的情况,剩余字符若没有出现数字3次则停止匹配.
var str = "123456789";
var reg = /\d{3,6}/g;
console.log(reg.exec(str)); //[ '123456', index: 0, input: '12345678', groups: undefined ]
console.log(reg.exec(str)); // [ '789', index: 6, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // null
11.2 非贪婪模式

尽可能少的匹配(每次取最少匹配的数量为一组进行匹配),直到匹配不到为止,使用方法:在量词后加上

// 对字符串"123456789",匹配其中的数字3-6次:\d{3,6},先匹配数字出现3次的字符串(123),然后再从剩余字符串(456789)中匹配出现数字3次的情况,剩余字符若没有出现数字3次则停止匹配.
var str = "123456789";
var reg = /\d{3,6}?/g;
console.log(reg.exec(str)); //[ '123', index: 0, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // [ '456', index: 3, input: '123456789', groups: undefined ]
console.log(reg.exec(str)); // [ '789', index: 6, input: '123456789', groups: undefined ]

12. 选择、分组、引用

12.1 选择

字符"|"用于分隔供选择的字符,选择项的尝试匹配次序是从左到右,知道发现了匹配项,如果左边的选择项匹配,就忽略右边的匹配项,即使它可以产生更好的匹配。

//   |  选择   类似于  或 a || b || c
//选择项的尝试匹配次序是从左到右,知道发现了匹配项,
// 如果左边的选择项匹配,就忽略右边的匹配项
var str = 'qqqwwwjscsshtmlcss';
var reg = /html|css|js/;
console.log(reg.exec(str));  //[ 'js', index: 6, input: 'qqqwwwjscsshtmlcss', groups: undefined ]
12.2 分组
// 分组
// var str = 'qqqwwwcsshtmlcss';
var str = 'i like css';
var reg = /i like html|css|js/;
console.log(reg.exec(str));  //[ 'css', index: 7, input: 'i like css', groups: undefined ]
12.3 捕获
// 捕获
var reg = /(\d{4})-(\d{2})-(\d{2})/
var date = '2021-08-29'
reg.test(date)
// 捕获之前要先test/exec
console.log(RegExp.$1); //2021
console.log(RegExp.$2); //08
console.log(RegExp.$3); //29
12.4 引用
// 引用
// is 前后一样才会返回true   否则返回false
var reg = /(\w{3}) is \1/;
console.log(reg.test('kid is kid'));  //true
console.log(reg.test('aaa is aaa'));  //true

13 String对正则表达式的支持

13.1 search

查找字符串中是否有匹配正则的字符串,有则返回字符串第一次出现时的位置,无则返回null。是否有全局匹配都不会影响返回结果。

// 引用
// is 前后一样才会返回true   否则返回false
var reg = /(\w{3}) is \1/;
console.log(reg.test('kid is kid'));  //true
console.log(reg.test('aaa is aaa'));  //true
13.2 match

匹配字符串中符合正则表达式的字符串,并返回该字符串的一个数组,其中包括字符串内容位置

如果正则设置全局匹配,则一次性返回所有符合正则表达式的字符串数组

如果其中添加了分组,返回符合要求的字符串以及分组的一个数组,但如果同时开启全局匹配则不会在数组中添加分组内容

/match
var str = 'hello world hello hello';
var reg1 = /hello/;
var reg2 = /hello/g;
var reg3 = /(he)llo/;
var reg4 = /(he)llo/g;
// 如果正则表达式没有开启全局匹配  那么match的用法和exec基本一样
console.log(str.match(reg1));  //[ 'hello',index: 0,input: 'hello world hello hello',groups: undefined ]
// 开启全局匹配  match会将所有匹配到的字符串放到一个数组内   返回给我们
console.log(str.match(reg2));  //[ 'hello', 'hello', 'hello' ]
// 添加了分组  返回符合要求的字符串以及分组的一个数组  类似exec
console.log(str.match(reg3));  //[ 'hello','he', index: 0,input: 'hello world hello hello',groups: undefined ]
// 如果同时开启全局匹配则不会在数组中添加分组内容
console.log(str.match(reg4));  //[ 'hello', 'hello', 'hello' ]
13.3 split
//split   以某种形式分割字符串
var str = 'larray123terry456zhangsan789lisi';
var reg = /\d+/;
console.log(str.split(reg));  //[ 'larray', 'terry', 'zhangsan', 'lisi' ]
13.4 replace
//replace   \b   \B
var str = 'Hello World Hello JavaScript';
var reg = /\bHello\b/g;
console.log(reg.exec(str));  //[ 'Hello',index: 0,input: 'Hello World Hello JavaScript',groups: undefined ]
console.log(str.replace(reg,'Hi'));  //Hi World Hi JavaScript

14 前瞻表达式

表达式名称描述
(?=exp)正向前瞻匹配后面满足表达式exp的位置
(?!exp)负向前瞻匹配后面不满足表达式exp的位置
var str = 'Hello, Hi, I am Hilary.';
//后面一定要匹配什么
var reg = /H(?=i)/g;
var newStr = str.replace(reg, "T");
console.log(newStr);  //Hello, Ti, I am Tilary.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值