【重温基础】9.正则表达式

本文是 重温基础 系列文章的第九篇。
今日感受:时间管理-角色管理法。

系列目录:

  • 【复习资料】ES6/ES7/ES8/ES9资料整理(个人整理)
  • 【重温基础】1.语法和数据类型
  • 【重温基础】2.流程控制和错误处理
  • 【重温基础】3.循环和迭代
  • 【重温基础】4.函数
  • 【重温基础】5.表达式和运算符
  • 【重温基础】6.数字
  • 【重温基础】7.时间对象
  • 【重温基础】8.字符串

本章节复习的是JS中的正则表达式,JS中用来匹配字符串的强大工具。

前置知识:
JS中的正则表达式是用来匹配字符串中指定字符组合的模式。
另外需要记住:正则表达式也是对象。

1.创建正则表达式

  • 使用一个正则表达式字面量:
let reg = /ab+c/;
let reg = /^[a-zA-z]/gi;
  • 使用RegExp对象:

new RegExp(str[, attr])接收2个参数,str是一个字符串,指定正则表达式匹配规则,attr可选,表示匹配模式,值有g(全局匹配),i(区分大小写的匹配)和m(多行匹配)。

let reg = new RegExp('ab+c');
let reg = new RegExp(/^[a-zA-z]/, "gi");
let reg = new RegExp("^[a-zA-z]", "gi");

正则表达式的返回值,是一个新的RegExp对象,具有指定的模式和标志。
返回信息介绍

对象属性描述案例中对应的值
reglastIndex下一个匹配的索引(仅在使用g参数时可用)0
regsource模式文本。在正则表达式创建时更新,不执行。"ab+c"
regignoreCase是否使用了 "i" 标记使正则匹配忽略大小写。true
regglobal是否使用了 "g" 标记来进行全局的匹配。true
regmultiline是否使用了 "m" 标记使正则工作在多行模式。false

关于正则表达式的一些方法属性,文章后面介绍,这里先复习定义和使用

2.使用正则表达式

JS的正则表达式可以被用于:

  • RegExp对象的exectest方法;
  • String对象的matchreplacesearchsplit方法。

2.1 RegExp对象方法

方法介绍
exec检索字符串中指定的值。返回找到的值,并确定其位置。
test检索字符串中指定的值。返回 truefalse

2.1.1 exec(str)

str: 需要检索的字符串。
若检索成功,返回匹配的数组,否则返回null。

let str = "hello leo!";
let reg = new RegExp("leo", "g");
let result = reg.exec(str);
// 也可以写成
let result = /leo/g.exec("hello leo!");

/*
[
    0: "leo",
    groups: undefined,
    index: 6,
    input: "hello leo!",
    length: 1
]
*/

let result2 = /(leo \S)/g.exec("hello leo hi leo!");
/*
    0: "leo hi"
    1: "leo hi"
    2: "hi"
    groups: undefined
    index: 6
    input: "hello leo hi leo!"
    length: 3
*/

返回信息介绍

对象属性描述案例中对应的值
result[0]匹配到的所有字符串"leo"
resultinput初始字符串。"hello leo!"
resultindex在输入的字符串中匹配到的以0开始的索引值。6
result2[1],...,[n]括号中的分组捕获[1]=> "leo hi";[2] => "hi"

2.1.2 test(str)

str:需要检索的字符串。
若匹配成功返回true否则false
等价于 reg.exec(str) != null

let str = "hello leo!";
let res = /^leo/.test(str);   // fasle
let res1 = /^leo/.test(str);  // true

^str表示匹配以str开头的字符串,这些符号文章后面会介绍。

2.2 String对象方法

方法介绍
search检索与正则表达式相匹配的值。
match找到一个或多个正则表达式的匹配。
replace替换与正则表达式匹配的子串。
split把字符串分割为字符串数组。

2.2.1 search

str.search(reg)
str:被检索的源字符串。
reg:可以是需要检索的字符串,也可以是需要检索的RegExp对象,可以添加标志,如i

若检索成功,返回第一个RegExp对象匹配的字符串的起始位置,否则返回-1

let str = "hello leo!";
let res = str.search(/leo/g);  // 6

let str1 = "hello leoleoleoleo!";
let res1 = str.search(/leo/g); // 6
let res2 = str.search(/pingan/g); // -1

2.2.2 match

str.match(reg)
str:被检索的源字符串。
reg:可以是需要检索的字符串,也可以是需要检索的RegExp对象,可以添加标志,如i

若检索成功,返回与reg匹配的所有结果的一个数组,数组的第一项是进行匹配完整的字符串,之后的项是用圆括号捕获的结果,否则返回null

let str = 'For more information, see Chapter 3.4.5.1';
let reg = /see (chapter \d+(\.\d)*)/i;
let result = str.match(reg);
/*
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' 属性是被解析的原始字符串。

2.2.3 replace

将字符串中指定字符替换成其他字符,或替换成一个与正则表达式匹配的字符串。
str.replace(sub/reg,val):

  • str: 源字符串
  • sub: 使用字符串来检索被替换的文本
  • reg: 使用RegExp对象来检索来检索被替换的文本
  • val: 指定替换文本

返回替换成功之后的字符串,不改变源字符串内容。

let str = "hello leo!";
let res = str.replace('leo','pingan');//"hello pingan!"

val可以使用特殊变量名

变量名代表的值
$$插入一个 "$"。
$&插入匹配的子串。
$插入当前匹配的子串左边的内容。
$'插入当前匹配的子串右边的内容。
$n假如第一个参数是 RegExp对象,并且 n 是个小于100的非负整数,那么插入第 n 个括号匹配的字符串。提示:索引是从1开始
let str = "hello leo!";
let res = str.replace(/(\w+)\s* \s*(\w+)/, "$2:$1");
// "leo:hello!"

2.2.4 split

将一个字符串,按照指定符号分割成一个字符串数组。
str.split(sub[, maxlength]):

  • str: 源字符串
  • sub: 指定的分割符号或正则
  • maxlength: 源字符串
let str = "hello leo!";
let res = str.split();   //["hello leo!"]
let res = str.split(""); //["h", "e", "l", "l", "o", " ", "l", "e", "o", "!"]
let res = str.split(" ");//["hello", "leo!"]
let res = str.split(/\s+/);//["hello", "leo!"]

let res = str.split("",3);//["h", "e", "l"]

2.3 使用情况

  • 当我们想要查找一个字符串中的一个匹配是否找到,可以用testsearch方法。
  • 当我们想要得到匹配的更多信息,我们就需要用到execmatch方法。

3.正则表达式符号介绍

详细的每个符号的用法,可以查阅 W3school JavaScript RegExp 对象

3.1 修饰符

修饰符描述
i执行对大小写不敏感的匹配。
g执行全局匹配(查找所有匹配而非在找到第一个匹配后停止)。
m执行多行匹配。
let str = "hello leo!"
let res = /Leo/i.test(str); // i 不区分大小写 所以返回true
let res = /Leo/.test(str);  // fasle

3.2 方括号

用于查找指定返回之内的字符:

表达式描述
[abc]查找方括号之间的任何字符。
[^abc]查找任何不在方括号之间的字符。
[0-9]查找任何从 0 至 9 的数字。
[a-z]查找任何从小写 a 到小写 z 的字符。
[a-z]查找任何从大写 A 到大写 Z 的字符。
[a-z]查找任何从大写 A 到小写 z 的字符。
[adgk]查找给定集合内的任何字符。
[^adgk]查找给定集合外的任何字符。
(red)查找任何指定的选项。
let str = "hello leo!";
let res = str.match(/[a-m]/g);
//["h", "e", "l", "l", "l", "e"]
let res = str.match(/[^a-m]/g);
//["o", " ", "o", "!"]

3.3 元字符

元字符是拥有特殊含义的字符:

元字符描述
.查找单个字符,除了换行和行结束符。
\w查找单词字符。
\w查找非单词字符。
\d查找数字。
\d查找非数字字符。
\s查找空白字符。
\s查找非空白字符。
\b匹配单词边界。
\b匹配非单词边界。
\0查找 NUL 字符。
\n查找换行符。
\f查找换页符。
\r查找回车符。
\t查找制表符。
\v查找垂直制表符。
\xxx查找以八进制数 xxx 规定的字符。
\xdd查找以十六进制数 dd 规定的字符。
\uxxxx查找以十六进制数 xxxx 规定的 Unicode 字符。
let str = "hello leo hi pingan!";
let res = str.match(/o\s/g);
//["o ", "o "]
let res = str.match(/\s/g);
//[" ", " ", " "]

3.4 量词

量词描述
n+匹配任何包含至少一个 n 的字符串。
n*匹配任何包含零个或多个 n 的字符串。
n?匹配任何包含零个或一个 n 的字符串。
n{X}匹配包含 X 个 n 的序列的字符串。
n{X,Y}匹配包含 X 至 Y 个 n 的序列的字符串。
n{X,}匹配包含至少 X 个 n 的序列的字符串。
n$匹配任何结尾为 n 的字符串。
^n匹配任何开头为 n 的字符串。
?=n匹配任何其后紧接指定字符串 n 的字符串。
?!n匹配任何其后没有紧接指定字符串 n 的字符串。
let str = "hello leo!";
let res = str.match(/^hello/g);
// ["hello"]
let res = str.match(/^pingan/g);
//null

4. 正则表达式拓展(ES6)

4.1 介绍

在ES5中有两种情况。

  • 参数是字符串,则第二个参数为正则表达式的修饰符。
let a = new RegExp('abc', 'i');
// 等价于
let a = /abx/i;
  • 参数是正则表达式,返回一个原表达式的拷贝,且不能有第二个参数,否则报错。
let a = new RegExp(/abc/i);
//等价于
let a = /abx/i;

let a = new RegExp(/abc/, 'i');
//  Uncaught TypeError

ES6中使用:
第一个参数是正则对象,第二个是指定修饰符,如果第一个参数已经有修饰符,则会被第二个参数覆盖。

new RegExp(/abc/ig, 'i');

4.2 字符串的正则方法

常用的四种方法:match()replace()search()split()

4.3 u修饰符

添加u修饰符,是为了处理大于uFFFF的Unicode字符,即正确处理四个字节的UTF-16编码。

/^\uD83D/u.test('\uD83D\uDC2A'); // false
/^\uD83D/.test('\uD83D\uDC2A');  // true

由于ES5之前不支持四个字节UTF-16编码,会识别为两个字符,导致第二行输出true,加入u修饰符后ES6就会识别为一个字符,所以输出false

注意:
加上u修饰符后,会改变下面正则表达式的行为:

  • (1)点字符

点字符(.)在正则中表示除了换行符以外的任意单个字符。对于码点大于0xFFFF的Unicode字符,点字符不能识别,必须加上u修饰符。

var a = "

相关推荐