之前在前端群和一群人聊天,有人提到了正则表达式,很多人都说,没必要深入了解正则表达式,拿来主义,有需要的时候直接网上找,都有现成的,我并不吃惊,因为我也是拿来主义,没有系统的学习过,或者说了解过正则表达式,但是出于好奇,百度了一下正则表达式,发现它并没有想象中那么简单,一旦真正学会它,我觉得在以后做项目中,会轻松很多,或者说思路会广阔很多,所以准备自己写一点学习正则的感悟和理解,以供自己以后复习。
申明正则表达式##
在JavaScript中,正则表达式其实是正则对象,也可以说成RegExp对象,既然是对象,那么就和对象声明一样,有2种方式声明,一种是直接字面量声明,如下:
var a = /^cat/i;
上述代码很简单,就是用字面量的方式创建了一个正则表达式。它的结构大概是这样的:
var 正则的名字 = /正则表达式/正则的标志(行为)
其中最复杂的应该就是正则表达式部分了,这个先不提,慢慢学吧。正则的标志有以下3种:
- g:表示的是全局模式,在这种模式下,这条正则规则将会去匹配你规定的所有字符串,而非发现一个匹配项就停止。
- i:表示匹配的字符串不区分大小写,在上述例子中,就可以理解为,匹配以cat,或者Cat,或者CAT等等开头的段落。
- m:表示多行模式,在这种模式下到达了一行文本的末尾会继续再下一行查找是否存在于之相匹配的。
正则的行为可以有多个。当然,还有第二种申明正则的方式,构造函数声明(new关键字),具体如下:
var a = new RegExp('^cat','i');
代码也很简单,结构大概是这样的:
var 正则的名字 = new RegExp('正则表达式','正则的标志')
2种方式都可以创建正则表达式,但是有一点要注意,字面量声明是在//里面声明,而构造函数声明传进去的参数是字符串,所有遇到一些\n
这样转义字符,需要双重转义,变成\\\n
,下面列出了一些例子:
字面量模式 | 构造函数模式的字符串 |
---|---|
/\[bc\]at/ | '\\[bc\\]at' |
/\.at/ | '\\.at' |
/\w\\hello\123/ | '\\w\\\\hello\\\\123' |
正则表达式的基础##
再上一个例子中,我们看到了
var a = /^cat/i
其中^cat
,^
是元字符,cat
为普通字符,元字符的意思就是说,比起普通字符有更多的含义,比如^
的意思就是一行的开始,与之相对应的还有$
元字符,代表一行的结束。
而^cat
可以理解为,匹配以cat
开头的行。当然,还有更准确的理解,匹配以c
作为一行的第一个字符,紧接着是a
,然后是t
的文本。因为正则匹配都是按照字符而不是单词,所以这样理解会更加准确一些。
下面总结一下常用的基础的正则表达式元字符:
元字符 | 名称 | 匹配对象 |
---|---|---|
. | 点号 | 单个任意字符 |
[···] | 字符组 | 并列出的任意字符 |
[ ^···] | 排除型字符组 | 未列出的任意字符 |
^ | 脱字符 | 行的起始位置 |
$ | 美元符 | 行的结束位置 |
< | 反斜线-小于 | 单词的起始位置 |
\> | 反斜线-大于 | 单词的结束位置 |
丨 | 竖线 | 匹配分隔两边的任意一个表达式 |
(···) | 括号 | 限制竖线的作用范围,分组匹配,反向引用等 |
表示重复的元字符:
元字符 | 次数下限 | 次数上限 | 含义 |
---|---|---|---|
? | 无 | 1 | 可以出现,也可以只出现一次(单次可选) |
* | 无 | 无 | 可以出现无穷多次,也可以不出现(任意次数均可) |
+ | 1 | 无 | 可以出现无穷多次,但至少要出现一次(至少一次) |
规定重复出现的次数范围:{min,max},如:
var a = /[0-9]{1,5}/ //匹配0至9的任意数字出现1至5次的行
正则实例方法##
JavaScript中,正则提供了2个方法。exec()和test()。
exec()
是专门为捕获组而设计的,它接受一个参数,即要作用的字符串,然后返回第一个匹配项信息的数组(没有匹配项返回null
),该数组中,第一项是整个模式匹配的字符串,其他项是与模式中捕获组的字符串(如果没有捕获组则只含有一项)。除此之外,该数组还包含2个属性,input
和index
,input
为作用的字符串,index
为匹配项在字符串中的位置。具体例子如下:
var text = '123456789CATCatCAtnnlsnfl'
var reg = /(cat)+/gi;
var match = reg.exec(text);
console.log(match[0]);//CATCatCAt
console.log(match[1]);//CAt
console.log(match.index);//9
console.log(match.input);//123456789CATCatCAtnnlsnfl
test()
方法相对来说就简单一点了,它接受一个字符串参数,匹配成功,返回true
,匹配失败,返回false
,所以常用在if判断句中。具体代码如下:
var text = '123456789CATCatCAtnnlsnfl'
var reg = /(cat)+/gi;
var reg2 = /(caat)+/gi;
var match = reg.test(text);
var match2 = reg.test(text);
console.log(match);//true
console.log(match2);//false
String对象里的正则##
string对象有很多方法都是支持正则的,比如search(),match()等等。下面,我们就来总结一下,string支持正则的方法。
search()
search()
方法支持传入一个参数,该参数可以是普通的字符串,也可以是一个正则表达式,如果是字符串,那就返回第一个符合条件的位置,同理,如果是正则表达式,就返回匹配正则表达式的位置,如果匹配失败,返回-1
,具体代码如下:
var text = '123456789CATCatCAtnnlsnfl'
var reg = /(cat)+/gi;
var match = text.search(reg);
var match2 = text.search('cat');
console.log(match);//9
console.log(match2);//-1
值得一提的是,在search()
中,会忽略正则表达式的g
标志,并且总是从字符串左向右匹配,一旦匹配到第一个符合条件的项就会立马结束匹配,并返回项所在的位置。
match()
match()
方法支持传入一个参数,该参数可以是普通的字符串,也可以是一个正则表达式,如果是字符串,那就返回一个以第一个匹配的字符串,并且有index
,input
属性的数组,其中,index
是第一个匹配成功的位置,input
是字符串本身,如果匹配失败,则返回null
;同理,如果是正则表达式,那就返回所有匹配成功的字符串组成的数组,并有input
,index
,具体代码如下:
var text = '123456789catCATCatCAtnnlsnflcAt'
var reg = /cat/gi;
var reg2 = /c.t/i;
var match = text.match(reg);
var match2 = text.match('cat');
var match3 = text.match(reg2);
console.log(match);//["cat", "CAT", "Cat", "CAt", "cAt"]
console.log(match2);//["cat", index: 9, input: "123456789catCATCatCAtnnlsnflcAt"]
console.log(match3);//["cat", index: 9, input: "123456789catCATCatCAtnnlsnflcAt"]
值得一提的是,如果正则表达式是全局匹配,即有g
标志,返回的只是一个所有符合条件的项的数组,而没有index
,input
属性。
replace()
replace()
方法接受2个参数,第一个参数是需要匹配的字符串或者正则表达式,第二个参数是替换的字符串。然后返回新的字符串。具体代码如下:
var text = '123456789catCATCatCAtnnlsnflcAt'
var reg = /(cat)+/gi;
var match = text.replace(reg,'dog');
var match2 = text.replace('cat','dog');
console.log(match);//123456789dognnlsnfldog
console.log(match2);//123456789dogCATCatCAtnnlsnflcAt
还没完!!在Perl
中,我们知道有括号的分组匹配,即,用括号能够‘记住’他们包含子表达式匹配的文本,在JavaScript中
的replace()
中也有与之类似的功能,不过写法不一样,JavaScript
,使用的是$
,可以用$
来得到括号里面的值并保留,具体如下:
var text = '123456789catCATCatCAtnnlsnflcAt'
var reg = /(cat)?(cat)/gi;
var match = text.replace(reg,' 1=$1 2=$2 ');
var match2 = text.replace('cat','dog');
console.log(match);//123456789 1=cat 2=CAT 1=Cat 2=CAt nnlsnflcAt
console.log(match2);//123456789dogCATCatCAtnnlsnflcAt
使用$1
可以去到第一个括号的值并保留,同理,可以一直向下取值。
当然,不仅仅只有$number
的用法,具体还有
符号 | 含义 |
---|---|
1....99 | 与regexp中的第1到第99个子表达式相匹配的文本。 |
$& | 与RegExp相匹配的子字符串。 |
lastMatch或RegExp["$_"] | 返回任何正则表达式搜索过程中的最后匹配的字符。 |
lastParen或 RegExp["$+"] | 返回任何正则表达式查找过程中最后括号的子匹配。 |
leftContext或RegExp["$`"] | 返回被查找的字符串从字符串开始的位置到最后匹配之前的位置之间的字符。 |
rightContext或RegExp["$'"] | 返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符。 |
split()
split()
接受2个参数, 第一个参数是一个字符串或者正则表达式,第二个参数可填可不填,是限制返回数组的最大长度。通过匹配字符串或者正则表达式,来对字符串进行切割,并返回一个切割的数组。具体代码如下:
var text = '1,2-3,4.5,6-7*8,9'
var reg = /[,-.*]*/gi;
var match = text.split(reg);
var match2 = text.split(',');
var match3 = text.split(reg,3);
console.log(match);//["1", "2", "3", "4", "5", "6", "7", "8", "9"]
console.log(match2);//["1", "2-3", "4.5", "6-7*8", "9"]
console.log(match3);//["1", "2", "3"]
JavaScript 正则表达式(1)
JavaScript 正则表达式(2)
JavaScript 正则表达式(3)
JavaScript 正则表达式(4)