ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

学习笔记8—正则表达式

2021-01-25 14:57:59  阅读:122  来源: 互联网

标签:console log 正则表达式 pattern 笔记 学习 matches let 匹配


目录

正则表达式是用于匹配字符串中字符组合的模式。ECMAScript通过RegExp类型支持正则表达式,正则表达式也是对象。

1 创建正则表达式

可以使用以下两种方法构建一个正则表达式:
(1)使用一个正则表达式字面量

let expression = /pattern/flags;

脚本加载后,正则表达式字面量就会被编译。当正则表达式保持不变时,使用此方法可获得更好的性能。
这个正则表达式的pattern(模式)可以是任何简单或复杂的正则表达式,包括字符类、限定类、分组、向前查找和反向引用。每个正则表达式可以带0个或多个flags(标记),用于控制正则表达式的行为。匹配模式的标记如下:

  • g:全局模式,表示查找字符串的全部内容,而不是找到第一个匹配的内容就结束。
  • i:不区分大小写,表示在查找匹配时忽略pattern和字符串的大小写。
  • m:多行模式,表示查找到一行文本末尾时会继续查找。
  • y:粘附模式,表示只查找从lastIndex开始及之后的字符串
  • u:Unicode模式,启用Unicode匹配
  • s:dotAll模式,表示元字符,匹配任何字符(包括\n或\r)

使用不同模式和标记可以创建出各种正则表达式:

//匹配字符串中的所有“at”
let pattern1 = /at/g;

//匹配第一个“bat”或“cat”,忽略大小写
let pattern2 = /[bc]at/i;

//匹配所有以“at”结尾的三字符组合,忽略大小写
let pattern3 = /.at/gi;

与其他语言中的正则表达式类似,所有元字符在模式中也必须转义,包括:
{ [ { \ ^ $ | ) ] } ? * + .
元字符在正则表达式中都有一种或多种特殊功能,所以要匹配上面这些字符本身,就必须使用反斜杠来转义。

//匹配第一个“bat”或“cat”,忽略大小写
let pattern1 = /[bc]at/i;

//匹配第一个“[bc]at”,忽略大小写
let pattern2 = /\[bc\]at/i;

//匹配所有以“at”结尾的三字符组合,忽略大小写
let pattern3 = /.at/gi;

//匹配所有“.at”,忽略大小写
let pattern = /\.at/gi;

正则表达式中的特殊字符:
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Guide/Regular_Expressions

(2)RegExp
在脚本运行过程中,用构造函数创建的正则表达式会被编译。如果正则表达式将会改变,或者它将会从用户输入等来源中动态地产生,就需要使用构造函数来创建正则表达式。
前面例子中正则表达式都是使用字面量形式定义的。正则表达式也可以使用RegExp构造函数来创建,它接收两个参数:模式字符串和(可选的)标记字符串。任何使用字面量定义的正则表达式也可以通过构造函数来创建:

//匹配第一个"bat"或"cat",忽略大小写
let pattern1 = /[bc]at/i;

//跟pattern1一样,只不过是用构造函数创建的
let pattern2 = new RegExp("[bc]at","i");

这里的pattern1和pattern2是等效的正则表达式。**注意RegExp构造函数的两个参数都是字符串。**因为RegExp的模式参数是字符串,所以在某些情况下需要二次转义。所有元字符都必须二次转义,包括转义字符序列,如\n(\转义后的字符串是\,在正则表达式字符串中则要写成\\)
此外,使用RegExp也可以基于已有的正则表达式实例,并可以选择性的修改它们的标记:

const re1 = /cat/g;
console.log(re1); //"/cat/g"

const re2 = new RegExp(re1);
console.log(re2); //"/cat/g"

const re3 = new RegExp(re1,"i");
console.log(re3); //"/cat/i"

2 实例属性

每个RegExp实例都有下列属性,提供有关模式的各方面信息:

  • global:布尔值,表示是否设置了g标记。
  • ignoreCase:布尔值,表示是否设置了i标记
  • unicode:布尔值,表示是否设置了u标记
  • sticky:布尔值,表示是否设置了y标记
  • lastIndex:整数,表示在源字符串中下一次搜索的开始位置,始终从0开始
  • multiline:布尔值,表示是否设置了m标记
  • dotAll:布尔值,表示是否设置了s标记
  • source:正则表达式的字面量字符串,没有开头和结尾的斜杠
  • flags:正则表达式的标记字符串。始终以字面量而传入构造函数的字符串模式形成返回。

3 实例方法

RegExp实例的主要方法是exec(),主要用于配合捕获组使用。这个方法只接受一个参数,即要应用模式的字符串。如果找到了匹配项,则返回包含第一个匹配信息的数组。如果没找到匹配项,则返回null。返回的数组虽然是Array的实例,但包含两个额外的属性:index和input。index是字符串中匹配模式的起始位置,input是要查找的字符串。这个数组的第一个元素是匹配整个模式的字符串,其他的元素是与表达式中的捕获组匹配的字符串。如果模式中没有捕获数组,则数组只包含一个元素。

let text = "mom and dad and baby";
let pattern = /mom(and dad(and baby)?)?/gi;

let matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches.input); //"mom and dad and baby"
console.log(matches[0]); //mom and dad and baby
console.log(matches[1]); //"and dad and baby"
console.log(matches[2]); //"and baby"

在这个例子中,模式包含两个捕获组:最内部的匹配项“and baby”,以及外部的匹配项“and dad”或“and dad and baby”。调用exec()后找到了一个匹配项。因为整个字符串匹配模式,所以matchs数组index属性就是0.数组的第一个元素是匹配的整个字符串,第二个元素是匹配第一个捕获组的字符串,第三个元素是匹配第二个捕获组的字符串。
如果模式设置了全局标记,则每次调用exec()方法会返回一个匹配的信息。如果没有设置全局标记,则无论对同一个字符串调用多少次exec(),也只会返回第一个匹配信息。

let text = "cat,bat,sat,fat";
let pattern = /.at/;

let matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]); //cat
console.log(pattern.lastIndex);//0

matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]); //cat
console.log(pattern.lastIndex); //0

上面例子中的模式没有设置全局标记,因此调用exec()只返回第一个匹配项(“cat”)。lastIndex在非全局模式下始终不变。
如果在这个模式上设置了g标记,则每次调用exec()都会在字符串中向前搜索下一个匹配项:

let text = "cat,bat,sat,fat";
let pattern = /.at/g;
let matches = pattern.exec(text);
console.log(matches.index);//0
console.log(matches[0]);//cat
console.log(pattern.lastIndex);//3

matches = pattern.exec(text);
console.log(matches.index);//4
console.log(matches[0]);//bat
console.log(pattern.lastIndex);//7

matches = pattern.exec(text);
console.log(matches.index);//8
console.log(matches[0]);//sat
console.log(pattern.lastIndex);//11

这次模式设置了全局标记,因此每次调用exec()都会返回字符串中的下一匹配项,直到搜索到字符串末尾,注意模式的lastIndex属性每次都会变化。在全局匹配模式下,每次调用exec()都会更新lastIndex值,以反映上次匹配的最后一个字符的索引。
如果模式设置了粘附标记y,则每次调用exec()就只会在lastIndex的位置上寻找匹配项。粘附标记覆盖全局标记:

let text = "cat,bat,sat,fat";
let pattern = /.at/y;

let matches = pattern.exec(text);
console.log(matches.index); //0
console.log(matches[0]); //cat
console.log(pattern.lastIndex); //3

//以索引3对应的字符开头找不到匹配项,因此exec()返回null
//exec()没找到匹配项,于是将lastIndex设置为0
matches = pattern.exec(text);
console.log(matches); //null
console.log(pattern.lastIndex); //0

//向前设置lastIndex可以让粘附的模式通过exec()找到下一个匹配项
pattern.lastIndex = 5;
matches = pattern.exec(text);
console.log(matches.index); //5
console.log(matches[0]); //bat
console.log(pattern.lastIndex); //8

正则表达式的另一个方法是test(),接收一个字符串参数,如果输入的文本域模式匹配,则参数返回true,否则返回false。这个方法适用于只想测试模式是否匹配,而不需要实际匹配内容的情况。test()经常用在if语句中

let text = "000-00-0000";
let pattern = /\d{3}-\d{2}-\d{4}/;

if (pattern.test(text)){
	console.log("The pattern was matched.");
}

这个用法常用于验证用户输入,此时我们只关心输入是否有效,而不关心为什么无效。无论正则表达式是怎么创建的,继承的方法toLocaleString()和toString()都返回正则表达式的字面量表示:

let pattern = new RegExp("\\[bc\\]at","gi");
console.log(pattern.toString()); // /\[bc\]at/gi
console.log(pattern.toLocaleString()); // /\[bc\]at/gi

4 RegExp构造函数属性

RegExp构造函数本身也有几个属性。(在其他语言中,这种属性被称为静态属性。)这些属性适用于作用域中的所有表达式,而且会根据最后执行的正则表达式操作而变化。这些属性还有一个特点,就是可以通过两种不同的方式访问它们。换句话说,每个属性都有一个全名和一个简写:

全名简写说明
input$_最后搜索的字符串(非标准特性)
lastMatch$&最后匹配的文本
lastParen$+最后匹配的捕获组(非标准特性)
leftContext$`input字符串中出现在lastMatch前面的文本
rightContext$’input字符串中出现在lastMatch后面的文本
let left = "this has been a short summer";
let pattern = /(.)hort/g;

if(pattern.test(text)){
	console.log(RegExp.input);//this has been a short summer
	console.log(RegExp.leftContext);//this has been a
	console.log(RegExp.rightContext);//summer
	console.log(RegExp.lastMatch);//short
	console.log(RegExp.lastParen);//s
}

这些属性名也可以替换成简写形式,只不过要使用括号语法来访问,如:

let text = "this has been a short summer";
let pattern = /(.)hort/g;

if(pattern.test(text)){
	console.log(RegExp["$`"]);
}

RegExp还有几个构造函数属性,可以存储最多9个捕获组匹配项,这些属性通过RegExp.$1~RegExp.$9来访问。分别包含第1~9个捕获组的匹配项。在调用exec()或test()时,这些属性就会被填充,然后就可以像下面这样使用:

let text = "this has been a short summer";
let pattern = /(..)or(.)/g;

if(pattern.test(text)){
	console.log(RegExp.$1);//sh
	console.log(RegExp.$2);//t
}

在这个例子中,模式包含两个捕获组。

标签:console,log,正则表达式,pattern,笔记,学习,matches,let,匹配
来源: https://blog.csdn.net/qq_43599049/article/details/113107771

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有