ES6学习笔记(七)正则表达式

2023-03-04 16:48:00 浏览数 (1)

本文最后更新于 128 天前,其中的信息可能已经有所发展或是发生改变。

正则表达式

1、基础

1.1 含义:

通俗的来讲,正则表达式是一种匹配和替换的工具。如:在JS中验证手机号时,我们需要考虑用户输入的字符必须是number类型,且必须是11位的整数,且数字的前三位必须是134,155,183,188,199等等。对于这一问题,可以用if-else来实现,只不过太过于麻烦,而正则表达式就将这一问题简单化。

1.2 组成部分

一个完整的正则表达式由分隔符,表达式,修饰符三部分组成。 分隔符指的是除了特殊字符以外的任意字符 表达式指的是由一些特殊字符以及非特殊字符串组成 修饰符用于开启或关闭某些功能 举个例子:

代码语言:javascript复制
let str = "1a2b3c4d5e6"
let reg = /[abcdef]/g
// 这里表示匹配abcdef这一类的字符,匹配成功就用-进行替换
console.log(str.replace(reg, '-')); // 1-2-3-4-5-6

其中,reg中的第一个/是分隔符,两个/之间的[abcef]是表达式,g是修饰符,表示全局匹配。常见的修饰符还有i表示忽略字母大小写,m表示多行搜索,搜索时识别换行符

1.3 语法

1、常见字符

字符

描述

[ABC]

匹配某类字符,如:[abc] 表示匹配某字符串中abc

^[ABC]

匹配某种字符之外的所有字符,如:[abc] 表示匹配某字符串中除abc之外的所有字符

[A-Z]

匹配所有大写字母

[a-z]

匹配所有小写字母

[s]

匹配空白符,包括f 换页符,r 回车符,t 水平制表符,n 换行符,x0b 垂直制表符等

[S]

匹配非空白符

w

匹配单词字符,包括数字,字母,下划线

W

匹配非单词字符,除数字,字母,下划线之外的所有字符

.(点)

匹配除了回车符和换行符之外的所有字符

d

匹配数字字符,等同于[0-9]

D

匹配非数字字符,等同于^[0-9]

2、特殊字符和限定符

字符

描述

$

匹配输入字符串的结尾位置

*

匹配前面的子表达式零次或多次

匹配前面的子表达式一次或多次

?

匹配前面的子表达式零次或一次,或指明一个非贪婪限定符

^

匹配输入字符串的开始位置

( )

标记一个子表达式的开始和结束位置

|

指明两项之间的一个选择

{n}

n 是一个非负整数。匹配确定的 n 次

{n,}

n 是一个非负整数。至少匹配n 次

{n,m}

m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次

注意: 和 *都是贪婪的,它们会尽可能多的匹配,只有在它们的后面加上一个 ? 就可以实现非贪婪或最小匹配 举个例子:

  • do 能匹配 "d" 以及 "doo"。 等价于{0,}
  • ‘do ’ 能匹配 "do" 以及 "doo",但不能匹配 "d"。 等价于 {1,}
  • "do(es)?" 可以匹配 "do" 、 "does" 中的 "does" 。? 等价于 {0,1}
  • ‘o{2}’ 不能匹配 "do" 中的 ‘o’,但是能匹配 "food" 中的两个 o
  • ‘o{2,}’ 不能匹配 "do" 中的 ‘o’,但是能匹配 "food" 中的两个 o以及"foood"中的3个o
  • ‘o{2,5}’ 不能匹配 "do" 中的 ‘o’,但是能匹配 "food" 中的两个 o以及"foood"中的3个o以及"fooood"中的4个o

1.4 正则表达式对象

JavaScript中使用RegExp对象来封装一个正则表达式,并提供相关的方法和属性。有两种创建方法,分别如下:

  • 字面量创建方法
代码语言:javascript复制
let reg = /bisb/g;  //表示全局匹配左右的单词边界为is的所有字符
let str = "He is a boy. This is a dog. Where is she?";
// 这里的3个is左右两边都有完整的单词,都会匹配。
console.log(str.replace(reg, "IS"));  // He IS a boy. This IS a dog. Where IS she?
  • 构造函数创建方法
代码语言:javascript复制
let reg = new RegExp("\bis\b", "g");
let str = "He is a boy. This is a dog. Where is she?";
console.log(str.replace(reg, "IS")); // He IS a boy. This IS a dog. Where IS she?

1.5 字符类

一般情况下,正则表达式一个字符对应字符串的一个字符。 例如:表达式 abt 的含义是 "ab"紧接着一个 tab(制表符)。

当需要匹配一类字符时,可以使用[ ]来构造一个简单的类。 所谓类,是指符合某些特性的对象,一个泛指,而不是特指某个字符。 例如:表达式[abc]把字符 a、b、c 归位一类,表达式可以匹配这类字符,即匹配其中之一。如:

代码语言:javascript复制
let str = "a1b2c3d4"; 
let reg = /[abc]/g // 表示全局匹配字符a,b,c
console.log(str.replace(reg, "x")); // x1x2x3d4

使用元字符^创建反向类(负向类),即匹配不属于该类的字符。 例如:[^abc]表示不是字符 a、b、c 其中之一的字符。如:

代码语言:javascript复制
let str = "a1b2c3d4"; 
let reg = /[^abc]/g // 表示全局匹配字符a,b,c
console.log(str.replace(reg, "x")); // axbxcxxx

1.6 范围类

需要匹配数字时,可以使用范围类。 例如:[a-z]表示从 a 到 z 之间的任意字符,且包含 a 和 z 本身。如:

代码语言:javascript复制
let str = "a1b2c3d4z0";
console.log(str.replace(/[a-z]/g, "X"));  //全局匹配所有的小写字母并替换成X,输出结果 X1X2X3X4X0

在[ ]中可以将一些范围连续书写

代码语言:javascript复制
let str = "a1b2c3D5E6F7";
console.log(str.replace(/[a-zA-Z0-9]/g, "*")); // 全局匹配大小写字幕和数字并替换成*  输出 ************
str = "1998-09-19";
console.log(str.replace(/[0-9-]/g, "0")); //全局匹配数字和下换线并替换成0 输出结果 0000000000

1.7 边界

字符

描述

^

以 xxx 开始

$

以 xxx 结束

b

单词边界

B

非单词边界

举个例子:

代码语言:javascript复制
let str = "This is a boy";
console.log(str.replace(/is/g, "0")); // 全局匹配所有的is,输出Th0 0 a boy
console.log(str.replace(/bisb/g, "0")); // This 0 a boy
console.log(str.replace(/Bisb/g, "0"));// 全局匹配左边界不是完整单词右边界是单词的字符,输出Th0 is a boy
代码语言:javascript复制
let str = "@123@abc@";
console.log(str.replace(/@./g, "Q")); // 全局匹配@以及后面跟任意字符的字符,输出Q23Qbc@
console.log(str.replace(/^@./g, "Q")); // 全局匹配以@开头以及后面跟任意字符的字符,输出Q23@abc
console.log(str.replace(/.@/g, "Q")); // 全局匹配任意字符后跟@的字符,输出@12QabQ
console.log(str.replace(/.@$/g, "Q")); // 全局匹配任意字符后跟以@结尾的字符,输出@123@abQ
代码语言:javascript复制
str = `@123
@456
@789`;
console.log(str.replace(/^@d/g, "X"));
/* 这里表示全局匹配以@开头的数字字符进行替换,因此输出:
X23
@456
@789 */
console.log(str.replace(/^@d/gm, "X"));
/* 这里表示全局匹配,多行搜索以@开头的数字字符进行替换,因此输出:
X23
X56
X89 */

1.8 分组,或,反向引用,忽略分组

  • 分组()
代码语言:javascript复制
let str = "a1b2c3d4"
console.log(str.replace(/[a-z]d{3}/g, "X"));  // 表示单独匹配3次小写字母和数字,输出a1b2c3d4
console.log(str.replace(/([a-z]d){3}/g, "X"));  // 表示匹配3次小写字母和数字组成的分组,输出Xd4
  • 或 |,表示左右字符二选一
代码语言:javascript复制
console.log("ByronCasper".replace(/Byron|Casper/g, "X")); // 全局匹配Byron或者Casper并进行替换,输出XX
console.log("ByrCasperByronsper".replace(/Byr(on|Ca)sper/g, "X")); // 全局匹配Byronsper或者ByrCasper并进行替换,输出XX
  • 反向引用:使用$n的形式引用模式中分组匹配到的文本,n为索引,从1开始,如:把 2020-03-04 替换成 03/04/2020,代码如下:
代码语言:javascript复制
// $n 反向引用
console.log("2020-03-04".replace(/(d{4})-(d{2})-(d{2})/g, "$2/$3/$1")); // 表示先全局匹配4位数字-2位数字-2位数字各分组组成的字符串,再通过索引排序,并将-替换成/ 输出03/04/2020
  • 忽略分组:当不想捕获分组时,可以使用?:直接输出$n,如:
代码语言:javascript复制
// 忽略分组
console.log("2020-03-04".replace(/(d{4})-(d{2})-(?:d{2})/g, "$2/$3/$1")); // 03/$3/2020

1.9 前瞻

  • 前瞻分为正向前瞻exp(?=assert)和负向前瞻exp(?!assert)
  • exp 和 assert 都是正则表达式,匹配到 exp 时还要判断 assert 是否符合,如果符合才会被匹配。 例如:表达式w(?=d),表示匹配到一个单词w 时还需要向后判断是否为一个数字d
代码语言:javascript复制
console.log("a2*34V8".replace(/w(?=d)/g, "X")); // X2*X4X8
console.log("a2*34V8".replace(/w(?!d)/g, "X")); // aX*3XVX

2、JavaScript中的正则表达式

2.1 RegExp对象属性

global,是否全文搜索,默认 false。 ignoreCase,是否忽略大小写,默认 false。 multiline,是否多行搜索,默认 false。 lastIndex,当前表达式匹配内容的最后一个字符的下一个位置。 source,正则表达式的文本字符串。 举个例子:

代码语言:javascript复制
let reg1 = /w/;
let reg2 = /w/gim;
console.log(reg1.global); // false
console.log(reg1.ignoreCase); // false
console.log(reg1.multiline); // false
console.log(reg2.global); // true
console.log(reg2.ignoreCase); // true
console.log(reg2.multiline); // true
//以上三个属性都是只读的。
console.log(reg2.source); // w

2.2 RegExp对象方法

  • test(str),用于测试字符串参数中是否存在匹配正则表达式模式的字符串,返回 true 或 false。
  • exec(str),使用正则表达式模式对字符串执行搜索,并将更新全部 RegExp 对象的属性以反映匹配结果。
    • 如果没有匹配的文本则返回 null,否则会返回一个结果“数组”对象: [匹配到的文本, 与第 1 个分组相匹配的文本,与第 n 个分组相匹配的文本…]
    • index,声明匹配文本的第一个字符的位置
    • input,存放被检索的字符串 string

举个例子:

代码语言:javascript复制
let reg1 = /w{1,2}/g; // 表示1~2位单词字符(包括数字,字母,下换线)
console.log(reg1.test("ab,cd")); // ab,cd符合reg1的规则,输出true
console.log(reg1.exec("ab,cd")); // [ 'cd', index: 3, input: 'ab,cd', groups: undefined ]
console.log(reg1.source); // w{1,2}

2.3 字符串正则方法

  • search(reg),用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串。返回第一个匹配结果的 index,没有匹配到返回-1。不执行全局匹配。
  • match(reg),检索字符串以找到一个或多个与 regexp 匹配的文本,未找到返回 null,找到后返回一个数组。与 RegExp 的 exec()方法相同。
  • split(reg),利用 regexp 匹配结果作为分隔符对字符串进行分割,返回一个数组。
  • replace(reg, newStr),将 regexp 的匹配结果替换成 newStr,返回一个新字符串。 举个例子:
代码语言:javascript复制
let str = "<java> and <javascript> is deferent!";
console.log(str.match(/<S*>/g)); // [ '<java>', '<javascript>' ]
console.log(str.replace(/<(S*)>/g, "<<$1>>")); // <<java>> and <<javascript>> is deferent!
console.log(str.split(/[<>]/g)); // [ '', 'java', ' and ', 'javascript', ' is deferent!' ]

0 人点赞