• 正则表达式


    正则表达式

    正则表达式(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

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

     

    元字符

    名称

    匹配对象

    .

    点号

    单个任意字符(除回车 、换行 、行分隔符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.加非元字符,表示一些不能打印的特殊字符,具体如下表:

    符号        含义

    NUL 字符 uOOOO

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

    制表符u0009

    换行符u000A

    v 垂直制表符u000B

    f 换页符u000C

             回车符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 u000Bu0020u00A0u2028u2029]

    S 非空白字符,等同于[入f u000Bu0020u00A0u2028u2029]

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

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

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

    5.任意字符

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

    妥善的利用互补属性,可以得到一些巧妙的效果。比如,[sS]、[wW]、[dD]都可以表示任意字符

    //匹配任意字符

    console.log(/./.test(' '));//false

    console.log(/[sS]/.test(' '));//true

    console.log(/[dD]/.test(' '));//true

    3量词相关元字符

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

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

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

    //等价于

    /dddddd/;

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

    {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},而如果写为ab{2},{2}只限定b,如下:

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

     

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

    /d{15}(d{3})?/

     

    捕获

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

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

    /(d{4})-(d{2})-(d{2})/

     

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

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

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

    //在调用exec()或test()方法时,这些属性会被自动填充 console.log(/(d{4})-(d{2})-(d{2})/.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 = /(d{4})-(d{2})-(d{2})/;

    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 = /(d{4})-(d{2})-(d{2})/;

    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 b')); //false

    console.log(/^b/m.test('a b')); //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(/ab{2}/.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(只支持和$)

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

    ・命名分组(只支持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 = /^d{4}-d{2}-d{2}$/g;

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

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

     

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

     

    var pattern = /^d{4}-d{2}-d{2}$/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(/^(d{4})-(d{2})-(d{2})$/.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);

  • 相关阅读:
    python3给socket模块设置代理
    yield、greenlet与协程gevent
    线程池
    并发通信、生产者与消费者模型
    多进程和多线程
    非阻塞套接字与IO多路复用
    14.python模块之subprocess
    判断页面是否滑到底部
    @vue/cli 3.x 版本配置productionGzip提高性能
    vue跳转到指定位置
  • 原文地址:https://www.cnblogs.com/zai1/p/11216375.html
Copyright © 2020-2023  润新知