正则表达式

Posted zai1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了正则表达式相关的知识,希望对你有一定的参考价值。

正则表达式

正则表达式(regularexpression)描述了一种字符串匹配的模式(pattern),可以用来检查一个串是 否含有某种子串、将匹配的子串替换或者从某个串中取出符合某个条件的子串等。

1正则表达式基本介绍

javascript中的正则表达式用RegExp对象表示,有两种写法:一种是字面量写法;另一种是构造 函数写法

字面量写法

正则表达式字面量写法,又叫Perl写法,因为JavaScript的正则表达式特性借鉴自Perl。正则表达 式字面量定义为包含在一对斜杠/之间的字符,并且可以有3个模式修正符

let expression = /pattern/flags;

这里的patte rn就是指我们的字符串模式,而后面的flags则是指带的模式修正符。 JavaScript中的正则表达式支持下列3个模式修正符:

g:表示全局(global)模式,即模式将被应用于所有字符串,而并非在发现第一个匹配项时立即停

i:表示不区分大小写(case-insensitive)模式,即在确定匹配项时忽略模式与字符串的大小写

m:表示多行(multiline)模式,即在到达一行文本末尾时还会继续查找下一行中是否存在与模式匹 配的项

 

RegExp构造函数

和普通的内置对象一样,RegExp正则表达式对象也支持new RegExp。构造函数的形式来创建正 则。RegExp构造函数接收两个参数:要匹配的字符串模式(pattern)和可选的模式修正符(flags)。

let reg1 = /at/i;

//等同于

let reg2 = new RegExp("at","i");

需要注意无论是字面量,还是构造函数,返回的类型都为object

let reg1 = /at/i;

//等同于

let reg2 = new RegExp("at","i");

console.log(typeof reg1);//object

console.log(typeof reg2);//object

 

  字面量构建的正则表达式,那么大致可以分为4个部分:定界符,简单字符, 元字符和模式修正符。而如果是构造函数构建的正则表达式,则少了一个定界符,由简单字符, 元字符以及模式修正符组成。

简单字符在正则表达式中,就是字面的含义,比如/a/匹配a, /b/匹配b,这样的字符被称之为简 单字符,示例如下:

let reg = /dog/;

let str = "This is a big dog"; console.log(reg.test(str));//true

 

这里我们调用了正则表达式的实例方法test(),该方法如果和传入的字符串能够匹配,则返回 true,否则返回false

除了简单字符以外,还有一些字符,它们除了字面意思外,还有着特殊的含义,这些字符就是元字符。

 

元字符

名称

匹配对象

.

点号

单个任意字符(除回车\r、换行\n、行分隔符\u2028和段分隔符\U2029外)

[]

字符组

列出的单个任意字符

e

排除型字符 组

未列出的单个任意字符

?

问号

匹配0次或1次

*

星号

匹配0交或多次

+

加号

匹配1次或多次

a,b

区间量词

匹配至少a次,最多b次

^

 

脱字符

行的起始位置

$

美元符

行的结束位置

|

竖线

分隔两边的任意一个表达式

()

括号

限制多选结构的范围,标注量词作用的元素,为反向引用捕获 文本

 

转义字符

转义字符(escape)表示为反斜线\ +字符的形式,共有以下3种情况

 

1.因为元字符有特殊的含义,所以无法直接匹配。如果要匹配它们本身,则需要在它们前面加上 反斜杠\

console.log(/1+1/.test("1+1"));//false console.log(/1\+1/.test("1+1"));//true

但实际上,并非14个元字符都需要转义,右方括号]和右花括号}可以不用写转义字符,当然写了 也不会算你错

console.log(/]/.test("]"));//true console.log(/\]/.test("]"));//true

 

2.\加非元字符,表示一些不能打印的特殊字符,具体如下表:

符号        含义

\0 NUL 字符 \uOOOO

[\b] 匹配退格符\u0008,不要与\b混淆

\t 制表符\u0009

\n 换行符\u000A

\v 垂直制表符\u000B

\f 换页符\u000C

\r          回车符\u000D

\xnn        由十六进制数nn指定的拉丁字符

\uxxxx 由十六进制数xxxx指定的Unicode字符(\u4e00-\u9fa5代表中文)

\cX  控制符X,表示ctrl-[X],其中的X是A-Z之中任一个英文字母,用来匹配控制字符

 

3.  \加任意其他字符,默认情况就是匹配此字符,也就是说,反斜线\被忽略了

console.log(/\x/.test("x"));//true console.log(/\yat/.test("yat"));//true

 

2字符组相关元字符

  1. 字符组介绍

字符组(Character Class),有的翻译成字符类或字符集。简单而言,就是指用方括号表示的一组 字符,它匹配若干字符之

//匹配0-910个数字之一

let reg = /[0123456789]/;

console.log(reg.test("1"));//true

console.log(reg.test("a"));//false

 

注意:字符组中的字符排列顺序并不影响字符组的功能,出现重复字符也不会影响

[0123456789]

//等价于

[9876543210]

//等价于

[1234567890123456789]

 

2.范围

正则表达式通过连字符-提供了范围表示法,可以简化字符组

[0123456789]

//等价于

[0-9] [abcdefghijklmnopqrstuvwxyz]

//等价于

[a-z]

 

 

连字符-表示的范围是根据ASCI I编码的码值来确定的,码值小的在前,码值大的在后 所以[0-9 ]是合法的,而[9-0]会报错

//匹配0-910个数字之一

let reg1 = /[0-9]/; console.log(reg1.test("1"));//true

let reg2 = /[9-0]/;//报

console.log(reg2.test("1"));

//SyntaxError: Invalid regular expression/[9-0]/:

//Range out of order in character class

在字符组中可以同时并列多个-范围

//[0—9a—zA—Z];匹配数字、大写字母和小写字母

//[0-9a-fA-F];匹配数字,大、小写形式的a-f,用来验证十六进制字符 console.log(/[0-9a-fA-F]/.test(‘d‘));//true

console.log(/[0-9a-fA-F]/.test(‘x‘));//false

 

有在字符组内部,连字符-才是元字符,表示一个范围,否则它就只能匹配普通的连字符号。 注意:如果连字符出现在字符组的开头或末尾,它表示的也是普通的连字符号,而不是一个范围

//匹配中划线

console.log(/-/.test(‘-‘));//true console.log(/[-]/.test(‘-‘));//true

//匹配0-9的数字或中划线

console.log(/[0-9]/.test(‘-‘));//false console.log(/[0-9-]/.test(‘-‘));//true

console.log(/[0-9\-]/.test(‘-‘));//true

console.log(/[-0-9]/.test(‘-‘));//true console.log(/[\-0-9]/.test(‘-‘));//true

 

3.排除

字符组的另一个类型是排除型字符组,在左方括号后紧跟一个脱字符八表示,表示在当前位置匹配一个没有列出的字符,所以[入0-9]表示0-9以外的字符

 

/匹配第一个是数字字符,第二个不是数字字符的字符串

 

console.log(/[0-9][^0-9]/.test(‘1e‘));//true

console.log(/[0-9][^0-9]/.test(‘q2‘));//false

 

注意:在字符组内部,脱字符八表示排除,而在字符组外部,脱字符八表示一个行锚点

八符号是元字符,在字符组中只要八符号不挨着左方括号就可以表示其本身含义,不转义也可

//匹配abc^符号

 

console.log(/[a-c^]/.test(‘^‘));//true console.log(/[a-c\^]/.test(‘^‘));//true console.log(/[\^a-c]/.test(‘^‘));//true

 

在字符组中,只有人-[]这4个字符可能被当做元字符,其他有元字符功能的字符都只表示其本 身,示例如下:在[]中的* + ?等元字符都是被当作其本身

//部分元字符示例

//这里会被当作是字面意思

 

console.log(/[1$]/.test(‘$‘)); //true

console.log(/[1|2]/.test(‘|‘)); //true

console.log(/[1?]/.test(‘?‘)); //true

console.log(/[1*]/.test(‘*‘)); //true

console.log(/[1+]/.test(‘+‘)); //true

console.log(/[1.]/.test(‘.‘)); //true

4.简记

用[0-9]、[a-z]等字符组,可以很方便地表示数字字符和小写字母字符。对于这类常用字符组,正 则表达式提供了更简单的记法,这就是字符组简记(shorthands)

常见的字符组简记有\d、\w、\s。其中d表示(digit)数字,w表示(word)单词,s表示(space) 空白

正则表达式也提供了对应排除型字符组的简记法:\D、\W、\S。字母完全相同,只是改为大 写。它们和小写的简记符在含义上刚好相反。

\d 数字,等同于[0-9]

\D 非数字,等同于[八0-9]

\s 空白字符,等同于[\f\n\r\t\u000B\u0020\u00A0\u2028\u2029]

\S 非空白字符,等同于[入\f\n\r\t\u000B\u0020\u00A0\u2028\u2029]

\w 字母、数字、下划线,等同于[0-9A-Za-z_](汉字不属于\w)

\W 非字母、数字、下划线,等同于[八0-9A-Za-z_]

注意:\w不仅包括字母、数字,还包括下划线。在进行数字验证时,只允许输入字母和数字 时,不可以使用\w,因为还包含了下划线。所以应该使用[0-9a-zA-Z]

5.任意字符

经常有人有一个误区就是认为点可以代表任意字符,其实并不是。点号.代表除回车(V),换行 (\n),行分隔符22028)和段分隔符(\u2029)以外的任意字符。

妥善的利用互补属性,可以得到一些巧妙的效果。比如,[\s\S]、[\w\W]、[\d\D]都可以表示任意字符

//匹配任意字符

console.log(/./.test(‘\r‘));//false

console.log(/[\s\S]/.test(‘\r‘));//true

console.log(/[\d\D]/.test(‘\r‘));//true

3量词相关元字符

据字符组的介绍,可以用字符组[0-9]或\d来匹配单个数字字符,如果用正则表达式表示更复杂 的字符串,则不太方便

//表示邮政编码6位数字

/[0-9][0-9][0-9][0-9][0-9][0-9]/;

//等价于

/\d\d\d\d\d\d/;

正则表达式提供了量词,用来设定某个模式出现的次数

n              匹配n次

n,m           匹配至少n次,最多m次

n,              匹配至少n次

 ?               相当于0,1

*                 相当于0,

+                相当于1,

 

美国英语和英国英语有些词的写法不一样,如果traveler和traveller, favor和favour, color和 colour

//同时匹配美国英语和英国英语单词

/travell?er/;

/favou?r

 

/colou?r/;

 

 

协议名有http和https两种

 

/https?/;

 

贪婪模式(扩展)

 

默认情况下,量词都是贪婪模式(greedy quantifier),即匹配到下一个字符不满足匹配规则为止

let reg = /a+/;

let str = "aaabbcc";

console.log(reg.exec(str));

//[ ‘aaa‘, index: 0, input: ‘aaabbcc‘ ]

 

这里我们使用了正则表达式的另外一个常用的实例方法exec()。该方法会返回一个数组,数组 里面有匹配上的字符,匹配上的索引值以及原始的字符串等更加详细的信息。

 

懒惰模式(扩展)

 

懒惰模式(lazy quantifier)和贪婪模式相对应,在量词后加问号?表示,表示尽可能少的匹配,一 旦条件满足就再不往下匹配

n?

匹配n次

n,m?

匹配至少n次,最多m次

n,?

匹配至少n次

??

相当于0,1

*?

相当于0,

+?

相当于1,

 

示例如下:

let reg = /a+?/;

let str = "aaabbcc";

console.log(reg.exec(str));

//[ ‘a‘, index: 0, input: ‘aaabbcc‘ ]

 

4括号相关元字符

 

括号有两个功能,分别是分组和引用。具体而言,用于限定量词或选择项的作用范围,也可以用 于捕获文本并进行引用或反向引用

分组

量词控制之前元素的出现次数,而这个元素可能是一个字符,也可能是一个字符组,也可以是一 个表达式。如果把一个表达式用括号包围起来,这个元素就是括号里的表达式,被称为子表达式 如果希望字符串"ab"重复出现2次,应该写为(ab)2,而如果写为ab2,2只限定b,如下:

console.log(/ab2/.test("abab"));//false console.log(/(ab)2/.test("abab"));//true

 

身份证长度有15位和18位两种,如果只匹配长度,可能会想当然地写成\d15,18,实际上这是 错误的,因为它包括15、16、17、18这四种长度。因此,正确的写法应该是

/\d15(\d3)?/

 

捕获

括号不仅可以对元素进行分组,还会保存每个分组匹配的文本,等到匹配完成后,引用捕获的内 容。因为捕获了文本,这种功能叫捕获分组

比如,要匹配诸如2016-06-23这样的日期字符串

/(\d4)-(\d2)-(\d2)/

 

与以往不同的是,年、月、日这三个数值被括号括起来了,从左到右为第1个括号、第2个括号和 3个括号,分别代表第1、2、3个捕获组。ES有9个用于存储捕获组的构造函数属性,如果使用 的是test()方法,那么通过正则对象的$1-$9属性可以访问到

//RegExp.$1\RegExp.$2\RegExp.$3....”至0RegExp.$9

//分别用于存储第一、第二”.”第九个匹配的捕获组。

//在调用exec()或test()方法时,这些属性会被自动填充 console.log(/(\d4)-(\d2)-(\d2)/.test(‘2016-06-23‘));//true

console.log(RegExp.$1);//2016

console.log(RegExp.$2);//06

console.log(RegExp.$3);//23

console.log(RegExp.$4);// " "

 

再例如:

let reg = /(a+)(b*)xj/;

let str = "aabbbxj"; console.log(reg.test(str));//true

console.log("$ 1 的值",RegExp.$1);//$1 的值:aa console.log("$2的值:",RegExp.$2);//$2的值:bbb

console.log("$3 的值",RegExp.$3);//$3 的值:

 

而exec()方法是专门为捕获组而设计的,返回的数组中,第一项是与整个模式匹配的字符串, 其他项是与模式中的捕获组匹配的字符串,如果要获取,那么可以通过指定数组的下标来进行获 取,如下:

let reg = /(\d4)-(\d2)-(\d2)/;

let str = "2017-03-21";

let i = reg.exec(str);

console.log(i);

//[ ‘2017-03-21‘, ‘2017‘, ‘03‘, ‘21‘, index: 0, input: ‘2017-03-21‘ ] console.log(i[1]);//2017

console.log(i[2]);//03

console.log(i[3]);//21

 

捕获分组捕获的文本,不仅可以用于数据提取,也可以用于替换

字符串的replaced方法就是用于进行数据替换的,该方法接收两个参数,第一个参数为待查 找的内容,而第二个参数为替换的内容

let str = "2017-12-12";

console.log(str.replace(/-/g,"."));

//2017.12.12

注意这里书写正则表达式的时候必须要写上模式修正符g,这样才能够进行全局匹配。 replace()方法中也可以引用分组,形式还是用$num,其中num是对应分组的编号

//把2017-03-23的形式变成03-23-2017

let reg = /(\d4)-(\d2)-(\d2)/;

let str = "2017-03-23"; console.log(str.replace(reg,"$2-$3-$1"));

//03-23-2017

 

5选择相关元字符

 

竖线|在正则表达式中表示或(OR)关系的选择,以竖线|分隔开的多个子表达式也叫选择分支 或选择项。在一个选择结构中,选择分支的数目没有限制。

在选择结构中,竖线|用来分隔选择项,而括号()用来规定整个选择结构的范围。如果没有出

现括号,则将整个表达式视为一个选择结构。

选择项的尝试匹配次序是从左到右,直到发现了匹配项,如果某个选择项匹配就忽略右侧其他选 择项,如果所有子选择项都不匹配,则整个选择结构匹配失败。

console.log(/12|23|34/.exec(‘1‘));//null

console.log(/12|23|34/.exec(‘12‘));//[ ‘12‘, index: 0, input: ‘12‘ ]

console.log(/12|23|34/.exec(‘23‘));//[ ‘23‘, index: 0, input: ‘23‘ ] console.log(/12|23|34/.exec(‘2334‘));//[ ‘23‘, index: 0, input: ‘2334‘ ]

 

在选择结构中,应该尽量避免选择分支中存在重复匹配,因为这样会大大增加回溯的计算量

//不良的选择结构

 

a|[ab]

[0-9]|\w

 

6断言相关元字符(扩展)

 

在正则表达式中,有些结构并不真正匹配文本,而只负责判断在某个位置左/右侧是否符合要 求,这种结构被称为断言(assertion),也称为锚点(anchor),常见的断言有3种:单词边界、行开 头结尾、环视

 

7模式修正符

 

匹配模式(match mode)又被称之为模式修正符。指的是匹配时使用的规则。设置特定的模式,可 能会改变对正则表达式的识别。前面已经介绍过创建正则表达式对象时,可以设

置m、i、g这三个标志,分别对应多行模式、不区分大小模式和全局模式三种

默认地,正则表达式是区分大小写的,通过设置标志‘i‘,可以忽略大小写(ignore case)

console.log(/ab/.test("aB"));//false

console.log(/ab/i.test("aB"));//true

m

默认地,正则表达式中的八和$匹配的是整个字符串的起始位置和结束位置,而通过设置标 志‘m‘,开启多行模式,它们也能匹配字符串内部某一行文本的起始位置和结束位置

console.log(/^b/.test(‘a\nb‘)); //false

console.log(/^b/m.test(‘a\nb‘)); //true

g

默认地,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹配(global),设 ‘g‘标志后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换

console.log(‘1a,2a,3a‘.replace(/a/,‘b‘)); //1b,2a,3a

console.log(‘1a,2a,3a‘.replace(/a/g,‘b‘)); //1b,2b,3b

 

8优先级

 

正则表达式千变万化,但是大多都是由之前介绍过的字符组、括号、量词等基本结构组合而成的。这些元字符,和运算符一样拥有一个优先级关系,如下:

//从上到下,优先级逐渐降

\                          转移符

() (?!) (?=) [ ]               括号、字符组、环视

* + ? n n, n,m          量词

^ $                       起始结束位置

|                        选择

 

 

由于括号的用途之一就是为量词限定作用范围,所以优先级比量词高

console.log(/ab2/.test(‘abab‘));//false console.log(/(ab)2/.test(‘abab‘));//true

|注意:选择符|的优先级最低,比起始和结束位置都要低

console.logWb|cd$/.test(‘abc‘ ));//true

console.log(/入(ab|cd)$/.test(‘abc‘));//false

console.log(/入(ab|cd)$/.test(‘ab‘));//true

console.log(/入(ab|cd)$/.test(‘cd‘));//true

 

9局限性

 

尽管JavaScript中的正则表达式功能比较完备,但与其他语言相比,缺少某些特性

下面列出了 JavaScript正则表达式不支持的特性

?POSIX字符组(只支持普通字符组和排除型字符组)

? Unicode支持(只支持单个Unicode字符)

?匹配字符串开始和结尾的\AW\Z(只支持和$)

?逆序环视(只支持顺序环视)

?命名分组(只支持0-9编号的捕获组)

?单行模式和注释模式(只支持m、i、g)

?模式作用范围

?纯文本模式

 

 

10正则表达式属性和方法

 

前面有提到,当我们使用typeof运算符来打印正则表达式的类型时,返回的是object ,这说 明正则表达式在JavaScript中也是一种对象。那么既然是对象,就应该有相应的属性和方法。

 

  1. 实例属性

每个RegExp实例对象都包含如下5个属性

  • global:布尔值,表示是否设置了g标志
  • ignoreCase:布尔值,表示是否设置了 i标志
  • IastIndex:整数,表示开始搜索下一个匹配项的字符位置,从0算起
  • multiline:布尔值,表示是否设置了标志m
  • source:正则表达式的字符串表示,按照字面量形式而非传入构造函数中的字符串模式返回

示例如下:

let reg = /test/gi;

console.log(reg.global);//true

console.log(reg.ignoreCase);//true

console.log(reg.multiline);//false

console.log(reg.lastIndex);//0

console.log(reg.source);//test

 

如果使用RegExp的exec()或test()函数,并且设定了全局模式g ,正则表达式的匹配就会 从lastindex的位置开始,并且在每次匹配成功之后重新设定lastindex ,继续往后匹配。 这样,就可以在字符串中重复迭代,依次寻找各个匹配结果。但是,如果需要对不同字符串调用 同一个RegExp的exec()或test()方法,这个变量也可能会带来意料之外的匹配结果,所以在更换字符串时,要显式地将RegExp的lastindex置为0

//exec()方法以数组形式返回匹配项

var reg = /\w/g;

var str = "abcd";

console.log(reg.lastIndex);//0

console.log(reg.exec(str));//[ ‘a‘, index: 0, input: ‘abcd‘ ]

console.log(reg.lastIndex);//1

console.log(reg.exec(str));//[ ‘b‘, index: 1, input: ‘abcd‘ ]

console.log(reg.lastIndex);//2

console.log(reg.exec(str));//[ ‘c‘, index: 2, input: ‘abcd‘ ]

console.log(reg.lastIndex);//3

console.log(reg.exec(str));//[ ‘d‘, index: 3, input: ‘abcd‘ ]

console.log(reg.lastIndex);//4

console.log(reg.exec(str));//null

console.log(reg.lastIndex);//0

console.log(reg.exec(str));//[ ‘a‘, index: 0, input: ‘abcd‘ ]

 2.构造函数属性(扩展)

RegExp构造函数属性被看成静态属性,这些属性基于所执行的最近一次正则表达式操作而变化 有两种方式访问它们,即长属性名和短属性名。短属性名大都不是有效的ECMAScript标识符, 所以必须通过方括号语法来访问

长属性名

短属性名

说明

input

$_

最近一次要匹配的字符串

lastMatch

$&

最近一次的匹配项

lastParen

$+

最近一次匹配的捕获组

leftContext

$`

input字符串中l astMatch之前的文本

multiline

$*

布尔值,表示是否所有表达式都使用多行模式

rightContext

 $’

input字符串中l astMatch之后的文本

 

使用这些属性,可以从exec()方法或test()方法执行的操作中提取出更具体的信息

 

3.实例方法

RegExp对象的实例方法共5个,分为两类。包 toString()、toLocalString()、valueOf()这3种对象通用方法和test()、exec()这2种正则匹配方法

对象通用方法(扩展)

RegExp对象继承了Object对象的通用方法 toString()、toLocaleString()、valueOf()这 三个方法

  • toString(): toString()方法返回正则表达式的字面量
  • toLocaleString(): toLocaleString()方法返回正则表达式的字面量
  • valueOf(): valueOf()方法返回返回正则表达式对象本身

注意:不论正则表达式的创建方式是哪种,这三个方法都只返回其字面量形式

 

let pattern1 = new RegExp(‘[bc]at‘,‘gi‘);

console.log(pattern1.toString()); // ‘/[bc]at/gi‘

console.log(pattern1.toLocaleString()); // ‘/[bc]at/gi‘

console.log(pattern1.valueOf()); // /[bc]at/gilet pattern2 = /[bc]at/gi;

console.log(pattern2.toString()); // ‘/[bc]at/gi‘

console.log(pattern2.toLocaleString()); // ‘[bc]at/gi‘

console.log(pattern2.valueOf()); // /[bc]at/gi

 

 

正则匹配方法

正则表达式RegExp对象的正则匹配方法只有两个:分别是test()和exec()

test()

test()方法用来测试正则表达式能否在字符串中找到匹配文本,接收一个字符串参数,匹配时 返回true,否则返回false

let reg = /test/;

let str = "this is a test"; console.log(reg.test(str));//true

 

在调用test()方法时,会造成RegExp对象的lastindex属性的变化。如果指定了全局模式 每次执行test()方法时,都会从字符串中的lastindex偏移值开始尝试匹配,所以用同一个 RegExp多次验证不同字符串,必须在每次调用之后,将lastindex值置为0

var pattern = /^\d4-\d2-\d2$/g;

console.log(pattern.test(‘2016-06-23‘));//true

console.log(pattern.test(‘2016-06-23‘));//false

 

//正确的做法应该是在验证不同字符串前,先将lastindex重置为0

 

var pattern = /^\d4-\d2-\d2$/g;

console.log(pattern.test(‘2016-06-23‘));//true

pattern.lastIndex = 0;

console.log(pattern.test(‘2016-06-23‘));//true

 

前面有介绍过,JS有9个用于存储捕获组的构造函数属性,在调用exec()或test()方法时,

这些属性会被自动填充。注意:理论上,应该保存整个表达式匹配文本的RegExp.$0并不存

在,值为 undefined

if(/^(\d4)-(\d2)-(\d2)$/.test(‘2016-06-23‘))

console.log(RegExp.$1);//‘2016‘

console.log(RegExp.$2);//‘06‘

console.log(RegExp.$3);//‘23‘

console.log(RegExp.$0);//undefined

 

exec()

 

 exec()方法专门为捕获组而设计,接受一个参数,即要应用模式的字符串。然后返回包含匹配 项信息的数组,在没有匹配项的情况下返回null

在匹配项数组中,第一项是与整个模式匹配的字符串,其他项是与模式中的捕获组匹配的字符 串,如果模式中没有捕获组,则该数组只包含一项

返回的数组包含两个额外的属性:index和input。index表示匹配项在字符串的位 置,input表示应用正则表达式的字符串

var text = ‘mom and dad and baby and others‘;

var pattern = /mom( and dad( and baby)?)?/gi;

var matches = pattern.exec(text); console.log(pattern,matches);

// /mom( and dad( and baby)?)?/gi [ ‘mom and dad and baby‘,

// ‘ and dad and baby‘,

// ‘ and baby‘,

// index: 0,

// input: ‘mom and dad and baby and others‘ ]

对于exec()方法而言,即使在模式中设置了全局标志g ,它每次也只会返回一个匹配项。在不 设置全局标志的情况下,在同一个字符串上多次调用exec(),将始终返回第一个匹配项的信息

var text = ‘cat,bat,sat,fat‘;

var pattern1 = /.at/;

var matches = pattern1.exec(text);

console.log(pattern1,matches);

///.at/ [ ‘cat‘, index: 0, input: ‘cat,bat,sat,fat‘ ]

var text = ‘cat,bat,sat,fat‘;

matches = pattern1.exec(text);

console.log(pattern1,matches);

///.at/ [ ‘cat‘, index: 0, input: ‘cat,bat,sat,fat‘ ]

 

而在设置全局标志的情况下,每次调用exec()都会在字符串中继续查找新匹配项

var text = ‘cat,bat,sat,fat‘;

var pattern2 = /.at/g;

var matches = pattern2.exec(text);

console.log(pattern2,matches);

///.at/g [ ‘cat‘, index: 0, input: ‘cat,bat,sat,fat‘ ]

var text = ‘cat,bat,sat,fat‘;

matches = pattern2.exec(text);

console.log(pattern2,matches);

///.at/g [ ‘bat‘, index: 4, input: ‘cat,bat,sat,fat‘ ]

 

注意:用exec()方法找出匹配的所有位置和所有值

var string = ‘j1h342jg24g234j 3g24j1‘;

var pattern = /\d/g;

var valueArray = [ ];//值

var indexA rray = [ ];//位置

var temp;

while((temp=pattern.exec(string)) != null) valueArray.push(temp[0]);

indexArray.push(temp.index);

//["1", "3", "4", "2", "2", "4", "2", "3", "4", "3", "2", "4", "1"] //[1, 3, 4, 5, 8, 9, 11, 12, 13, 16, 18, 19, 21] console.log(valueArray,indexArray);

以上是关于正则表达式的主要内容,如果未能解决你的问题,请参考以下文章

PHP 正则表达式总结

正则表达式

正则表达式

正则表达式“或“的使用

正则表达式 验证数字格式 非负数 小数点后保留两位 数字正则 double正则

JS正则表达式详解