js正则表达式

5,101 阅读7分钟
很多时候,我们对正则表达式的印象都是难学难记,学了又忘,忘了又学,但总觉得记不住。
什么是正则表达式?
正则表达式(Regular Expression)使用单个字符来描述、匹配一系列符合某个句法规则的字符串。
使用正则表达式的目的--替换工作。自己先定义一种规则,然后到字符串中去匹配一下符合这个规则的子字符串。
为了更好地理解正则表达式,我们可借助可视化工具,在线地址为:

Regexper:regexper.com
Regulex:jex.im/regulex/#!f…
Debuggex:www.debuggex.com/

先学习一下正则表达式的语法:

1、RegExp对象

js通过内置对象RegExp支持正则表达式,有2种方法实例化RegExp对象: a.字面量 b.构造函数
a.字面量
var reg = /\bare\b/g;

这里写图片描述
这里写图片描述

如何进行全文匹配?☞“g

这里写图片描述
这里写图片描述

b.构造函数
var reg = new RegExp('\\bare\\b','g');
第1个参数:字符串☞正则表达式的文本,js中“\”本身就是特殊字符,想使用的话需要转义;
第2个参数:字符串☞标识。

这里写图片描述
这里写图片描述

全文匹配-->“g”:

这里写图片描述
这里写图片描述

修饰符
g:global--全文搜索,不添加,搜索到第一个匹配为止;
i:ignore case--忽略大小写,默认大小写敏感;
m:multiple lines--多行搜索。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

发现:大写的单词未被替换,想要忽略大小写,无论大小写都能匹配☞“i”。

这里写图片描述
这里写图片描述

2、元字符

正则表达式由2种基本字符类型组成:1.原义文本字符, 2.元字符
元字符是在正则表达式中有特殊含义的非字母字符
* + ? $ ^ . | \ () {} []

这里写图片描述
这里写图片描述

3、字符类

一般情况下,正则表达式的一个字符对应字符串的一个字符。有时,希望匹配某类字符(即符合一系列特征的某类字符),该如何处理?
☞我们可以使用元字符[]来构建一个简单的类;
☞所谓类是指符合某些特性的对象,是一个泛指,而不是特指某个字符;
☞表达式[abc]把字符a或b或c归为一类,表达式可以匹配这类的字符。

这里写图片描述
这里写图片描述

字符类取反
a.使用元字符^创建反向类/负向类
b.反向类是指不属于某类的内容
c.表达式[^abc]表示不是字符a或b或c的内容

这里写图片描述
这里写图片描述

4、范围类

使用字符类匹配数字[0123456789]
可使用[a-z]来连接2个字符,表示从a到z的任意字符(这是个闭区间,即包含a和z本身)。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

在[]组成的类内部是可以连写的[a-zA-Z]

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

问:“-”并不是特殊字符,也不是元字符,有时在类里就想要匹配“-”时该如何?

这里写图片描述
这里写图片描述

记住:“-”在中间,即一个开头,一个结尾这样的语法里,表示范围。

这里写图片描述
这里写图片描述

这样就可匹配“-”了。

5、预定义类

这里写图片描述
这里写图片描述

匹配一个 ab+数字+任意字符 的字符串

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

正则表达式还提供了几个常用的边界匹配符

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

发现:凡有“is”的地方都做了替换。
只想替换单词“is”,单词是有单词边界的。

这里写图片描述
这里写图片描述

若只想替换“This”中的is,观察发现:前边不是边界,后面才是边界,于是有
这里写图片描述
这里写图片描述

注意:元字符的含义并不是唯一的,在不同的场景下有不同的含义,不在[]里的含义就不是取反了,而是表示“以xx开始”。

这里写图片描述
这里写图片描述

“.@”☞“任意字符+@”进行匹配
“@.”☞“@+任意字符”进行匹配
“.@$”☞“只想让@作为结尾”进行匹配

6、量词

我们希望匹配一个连续出现n次数字的字符串,如“\d\d\d\d\d\d\d\d\d\d......”,为了解决这样的问题,正则表达式引入了量词的概念。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

7、正则表达式的贪婪模式与非贪婪模式

a.贪婪模式

正则表达式在匹配时会尽可能多地匹配,直到匹配失败,默认是贪婪模式。

这里写图片描述
这里写图片描述

b.非贪婪模式

让正则表达式尽可能少地匹配,即一旦匹配成功就不再继续往下,这就是非贪婪模式。☞在量词后面加?即可。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

8、分组

匹配字符串javascript连续出现3次的场景,若这样写javascript{3},如下

这里写图片描述
这里写图片描述

量词只能针对于紧挨着它的字母,并不能作为整个单词。使用( )可达到分组的功能,使量词作用于分组。
(javascript){3},如下

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

使用 | 可达到的效果:

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

反向引用

2017-11-10 =>11/10/2017

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

替换的内容不再是常量,而是变量,此时该如何处理?☞“$”分组类的内容。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

用"$1"等来代表捕获的分组,又叫分组捕获。
利用分组,但又不想捕获它,该如何?☞忽略分组
不希望捕获某些分组,只需要在分组内加上? :即可。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

9、前瞻

正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前”,文本头部,称为“后”。
前瞻就是在正则表达式匹配到规则时,向前检查是否符合断言,后顾/后瞻方向反。
js不支持后顾。
符合特定断言称为肯定/正向匹配;不符合特定断言称为否定/负向匹配。

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

10、js对象属性

global:是否全文搜索,默认false。
ignore case:是否大小写敏感,默认false。
multiline:多行搜索,默认false。
lastIndex:是当前表达式匹配内容的最后一个字符的下一个位置。
source:正则表示式的文本字符串。
var reg1 = /\w/;
var reg2 = /\w/gim;

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

RegExp.prototype.test(str)☞用于测试字符串参数中是否存在匹配正则表达式模式的字符串。若存在则返回true,否则返回false。
var reg1 = /\w/;
var reg2 = /\w/g;

这里写图片描述
这里写图片描述

产生原因:受lastIndex影响。
var reg1 = /\w/;
var reg2 = /\w/g;
while(reg2.test('ab')){
    console.log(reg2.lastIndex);
}

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述

每次都只有第一遍是对的,于是,每次都给它实例化一个新的,但这需要用到内存开销。没必要这么做。

这里写图片描述
这里写图片描述

RegExp.prototype.exec(str)☞使用正则表达式模式对字符串执行搜索,并将更新全局RegExp对象的属性以反映匹配结果。
若没有匹配的文本则返回null,否则返回一个结果数组:
index声明匹配文本的第一个字符的位置
input存放被检索的字符串string

非全局调用

调用非全局的RegExp对象的exec()时,返回数组;
第一个元素是与正则表达式相匹配的文本;
第二个元素是与RegExpObject的第一个子表达式相匹配的文本(若有的话);
第三个元素是与RegExp对象的第二个子表达式相匹配的文本(若有的话),以此类推。
String.prototype.search(reg)
☞search()方法用于检索字符串中指定的子字符串,或检索与正则表达式相匹配的子字符串;
☞方法返回第一个匹配结果index,查找不到返回-1;
☞search()方法不执行全局匹配,它将忽略标志g,且总是从字符串的开始进行检索。
String.prototype.match(reg)
☞match()方法将检索字符串,以找到一个或多个与regexp匹配的文本;
☞regexp是否具有标志g对结果影响很大。
非全局调用
若regexp没有标志g,则match()方法就只能在字符串中执行一次匹配;若未找到任何匹配的文本,将返回null,否则,它将返回一个数组,其中存放了与它找到的匹配文本有关的信息;返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本;除了常规的数组元素之外,返回的数组还含有2个对象属性:index声明匹配文本的起始字符在字符串的位置;input声明对stringObject的引用。
全局调用
若regexp具有标志g则match()将执行全局搜索,找到字符串中的所有匹配子字符串,若未找到任何匹配的字符串,则返回null;若找到了一个或多个匹配字符串,则返回一个数组。
数组元素中存放的是字符串中所有的匹配子串,且也没有index属性或input属性。
String.prototype.split(reg)
常用split()把字符串分割为字符数组:'a,b,c,d'.split(',');//["a","b","c","d"]
复杂的分割情况下也可使用正则表达式解决:'a1b2c3d'.split(/\d/);//["a","b","c","d"]
String.prototype.replace
☞String.prototype.replace(str,replaceStr)
☞String.prototype.replace(reg,replaceStr)
☞String.prototype.replace(reg,function)

这里写图片描述
这里写图片描述

function参数含义
function会在每次匹配替换时调用,有4个参数:
1、匹配字符串
2、正则表达式分组内容,没有分组则没有该参数
3、匹配项在字符串中的index
4、原字符串

这里写图片描述
这里写图片描述

这里写图片描述
这里写图片描述