RegExp正则表达式(四)–js中与RegExp对象相关的方法

正则表达式的出现就是为了匹配预期的字符串,然后对匹配的字符串进行相应的处理。这些处理即是方法。

在js中,处理正则表达式的方法分为两大类:

  • 一类是RegExp对象中的方法;
  • 另一类是stringObj对象中处理RegExp对象的方法;

RegExp对象是在定义正则表达式的时候返回的。关于正则表达式的定义在上一篇中有详细的介绍,想要涉猎的,戳一下这里


RegExp对象中的方法

js中的RegExp对象方法有:

  • exec()方法
  • test()方法
  • compile()方法

本文在以下语法中出现的RegExp表示RegExp对象,str表示字符串,StringObj表示字符串对象。在展示语法时,不再赘述。


exec()方法

语法:

RegExp.exec(str);

该方法是比较复杂的。请听我细细道来……

如果匹配成功,该方法会返回一个数组;如果匹配失败,该方法会返回null。而匹配成功时又分为分为两种情况:

  • 一种是附加参数有g(全局匹配)的
  • 一种是附加参数没有g的

首先来分析有g时该方法的表现。如果匹配成功并且是全局匹配,那么该方法返回的数组中包括:

数组[0]=匹配到的字符串;(一定有的)
数组[1]=正则表达式中第一个子表达式匹配到的字符串;***子表达式是指小括号中的表达式***(如果有子表达式)
数组[2]=正则表达式中第二个子表达式匹配到的字符串;***子表达式是指小括号中的表达式***(如果有子表达式)
……
数组[“index”]=匹配到的字符串第一个字符在整个字符串中的索引位置***索引从0开始***
数组[“input”]=整个字符串

RegExp对象的 lastIndex 属性会返回字符串开始检索的位置,并且亦可以通过设置该属性,来控制开始检索的位置。

当exec()方法匹配成功时,它会将RegExp对象的 lastIndex 属性设置为该匹配成功的字符串最后一个字符的下一个位置。这样当你再次使用该RegExp对象调用exec()方法时,该方法就会从该位置开始检索匹配。

举个栗子

例1:

var reg = /\d+/g;
var str = "I am 27.I have 3 apples";
var arr = reg.exec(str);
//arr[0] => 27,
//arr["index"] => 5,
//arr["input"] => "I am 27.I have 3 apples"

reg.lastIndex = 0;
var j = 0;
while(arr=reg.exec(str)!=null){
  j++; 
  console.log("第"+j+"次循环");
   for(var i in arr){
        console.log(i+"===="+arr[i])
   }

}

/***
****控制台的日志会显示:

****第1次循环
****0====27
****index====5
****input====I am 27.I have 3 apples
****第2次循环
****0====3
****index====15
****input====I am 27.I have 3 apples

***/

例2:

var reg = /(have)\sa\s(\w+)/g
var str = "I have a pen,I have a apple.apple-pen";
var arr;

var j = 0;
while(arr=reg.exec(str)!=null){
  j++; 
  console.log("第"+j+"次循环");
   for(var i in arr){
        console.log(i+"===="+arr[i])
   }

}

/***
****控制台的日志会显示:

****第1次循环
****0====have a pen
****1====have
****2====pen
****index====2
****input====I have a pen,I have a apple.apple-pen
****第2次循环
****0====have a apple
****1====have
****2====apple
****index====15
****input====I have a pen,I have a apple.apple-pen

***/

接下来,我们来分析没有g时,该方法的表现

如果正则表达式中没有设置全局匹配(g),那么exec()方法匹配成功时,就会将RegExp对象中的 lastIndex 属性设置为0,使该RegExp对象下次匹配时继续从字符串开头的位置检索。该方法的返回的数组还是和上面全局匹配时的规则一样。此时exec()方法相当于StringObj对象的match()方法。

举个栗子

var reg = /abc/;//定义非全局匹配的正则表达式
var result;
while(result=reg.exec("ccabcbbabc")!=null){
    for(var i in result){
        console.log(i+"===="+result[i])
    }
}

/***
****此时该程序会进入死循环,因为每一次匹配都会从字符串起始位置进行检索****
****控制台的日志会显示:
****0====abc
****index====2
****input====ccabcbbabc
         ……
****0====abc
****index====2
****input====ccabcbbabc
***/

test()方法

该方法返回一个布尔值,即匹配成功返回true,匹配失败则返回false
其语法:

RegExp.test(str);

RegExp.test(str) 方法和 RegExp.exec(str)!=null 方法的效果是一样的。

如果正则表达式为全局匹配且匹配成功,那么RegExp.lastIndex 就会自动被设置成该匹配成功的字符串最后一个字符的下一个位置(这一点与exec()方法一样),下一次该RegExp对象再进行匹配时,就会把该位置当成检索的起始点。

如果正则表达式为非全局匹配且匹配成功,那么RegExp.lastIndex会自动被设置成0,下一次该RegExp对象再进行匹配时,就会从字符串的开头位置进行检索。

举个栗子

例1:

var reg = /abc/g;
var i = 0;
while(reg.test("ccabcbbabcs")){
    i++;
    console.log("第"+i+"次循环");
    console.log("lastIndex==="+reg.lastIndex);
}
/***
****第1次循环
****lastIndex===5
****第2次循环
****lastIndex===10
***/

例2:

var reg = /abc/;
var i = 0;
while(reg.test("ccabcbbabcs")){
    i++;
    console.log("第"+i+"次循环");
    console.log("lastIndex==="+reg.lastIndex);
}
/***
**********进入死循环**************
****第1次循环
****lastIndex===0
****第2次循环
****lastIndex===0
      ……
***/

compile()方法

该方法用于将正则表达式进行编译。
其语法为:

RegExp.compile(“正则表达式”,”附加参数”);

RegExp.compile(正则表达式/附加参数);

如果使用未编译的正则表达式,浏览器解析JS脚本时,每次遇到该正则表达式对象都会再次进行编译。所以使用编译过的正则表达式会提高代码的执行速度。

如果该正则表达式被多次调用,则执行效率会提升得更明显。

如果该正则表达式只被调用一两次,那么执行效率不会有太大的提升效果。

另外,compile()方法还可以对指定的正则表达式进行修改并且重新编译

举个栗子

例1:

var reg = /abc/gim;
reg.compile(reg);//将reg正则表达式对象编译/pen/gim
var i = 0;
while(reg.test("ccabcbbabcs")){
    i++;
    console.log("第"+i+"次循环");
    console.log("lastIndex==="+reg.lastIndex);
}
/***
****第1次循环
****lastIndex===5
****第2次循环
****lastIndex===10
***/

例2:

var reg = /abc/gim;
reg.compile("bb","gim");//将reg正则表达式对象重新编译成/pen/gim
//或者可以这样写:reg.compile(/bb/gim);
var i = 0;
while(reg.test("ccabcbbabcs")){
    i++;
    console.log("第"+i+"次循环");
    console.log("lastIndex==="+reg.lastIndex);
}
/***
****第1次循环
****lastIndex===7
***/

stringObj对象中处理RegExp对象的方法

字符串对象中有一些方法可以对RegExp对象进行操作,有:

  • match()方法
  • search()方法
  • split()方法
  • replace()方法

和正则表达式定义相似,var str=”abc”;var str=new String(“abc”); 这两种定义字符串的方法返回的都是StringObj(字符串对象)。


match()方法

语法:

StringObj.match(RegExp);

如果匹配成功并且是全局匹配,则该方法返回一个数组,数组中包括全部匹配的字符串;即:

数组[0]=第1个匹配的字符串
数组[1]=第2个匹配的字符串

数组[n]=第n+1个匹配的字符串

如果匹配成功并且是非全局匹配,则该方法返回一个数组,数组中包括:

数组[0]=第一个匹配的字符串
数组[1]=正则表达式中第一个子表达式匹配到的字符串;***子表达式是指小括号中的表达式***(如果有子表达式)
数组[2]=正则表达式中第二个子表达式匹配到的字符串;***子表达式是指小括号中的表达式***(如果有子表达式)
……
数组[“index”]=匹配的第一个字符的匹配位置(即和exec()方法中的index属性一样)
数组[“input”]=全部字符串(即和exec()方法中的input属性一样)

如果匹配失败,则返回null。 另外,该方法也会忽略 RegExp.lastIndex 设置的值,即无论lastIndex属性的值设置为多少,字符串都会从字符串开头的位置开始检索。

举个栗子

例1:

var reg = /user\d/g;
var str = "user13userddduser345";
var arr = str.match(reg);
//arr => ["user1","user3"];

例2:

var reg = /user\d/;
var str = "user13userddduser345";
var arr = str.match(reg);
//arr => ["user1"];
//arr["index"] => 0;
//arr["input"] => "user13userddduser345";

例3:

var reg = /localuser/g;
var str = "user13userddduser345";
var arr = str.match(reg);
//arr => null;

search()方法

语法:

StringObj.search(RegExp);

该方法忽略附加参数g,即无论是全局匹配还是非全局匹配,都不会影响返回结果。

如果匹配成功,则返回第一个匹配到的字符串的首字母的索引位置
如果匹配失败,则返回-1

另外,该方法也会忽略 RegExp.lastIndex 设置的值,即无论lastIndex属性的值设置为多少,字符串都会从字符串开头的位置开始检索。

举个栗子

例1:

var reg = /user\d/g;
var str = "**user13userddduser345";
var index = str.search(reg);
//index => 2

例2:

var reg = /user\d/;
var str = "**user13userddduser345";
var index = str.search(reg);
//index => 2

例3:

var reg = /localuser/;
var str = "**user13userddduser345";
var index = str.search(reg);
//index => -1

split()方法

语法:

StringObj.split(RegExp);

该方法忽略附加参数g,即无论是全局匹配还是非全局匹配都不会影响返回结果。

如果匹配成功,则返回一个数组。该字符串是以RegExp匹配的字符串作为分割的数组。
如果匹配失败,则返回一个数组。该数组只有一个成员,即原字符串。

另外,该方法也会忽略 RegExp.lastIndex 设置的值,即无论lastIndex属性的值设置为多少,字符串都会从字符串开头的位置开始检索。

举个栗子

例1:

var reg = /user/g;  
var str = "user13userddduser345";
var arr = str.split(reg);
//arr => ["","13","ddd","345"]
//var reg = /user/;的定义,arr的结果是一样

例2:

var reg = /localuser/g;  
var str = "user13userddduser345";
var arr = str.split(reg);
//arr => ["user13userddduser345"]
//var reg = /localuser/;的定义,arr的结果是一样

例3:

var reg = /user/g;  
var str = "**user13userddduser345";
var arr = str.split(reg);
//arr => ["**","13","ddd","345"]
//var reg = /user/;的定义,arr的结果是一样

replace()方法

语法:

StringObj.replace(RegExp,str);

StringObj.replace(RegExp,Function);

该方法的第二个参数有两种形式,一种是字符串类型,一种是函数类型。该函数可以有一个参数,该参数表示匹配到的字符串,并且该函数要有返回值。

该方法的作用是将StringObj字符串中符合RegExp对象匹配的子字符串替换成str或是Function函数返回的值,并将替换后的字符串作为返回值返回。

正则表达式的附加参数 g 会影响替换结果。

  • 如果没有 g,则只替换第一个匹配到的字符串;
  • 如果有 g,则替换所有匹配到的字符串。

另外,replace()方法中的第二个参数(字符串类型)中可以含有变量符号”$”,格式为 $ + n , n 从1开始计。其代表正则表达式的匹配被记住的第n个匹配字符串(即小括号的作用)。

变量符号 $ + n 是以字符串形式书写的。
如:

str.replace(reg,”\$1″);
//而非str.replace(reg,\$1)

如果要替换成”$”符号本身,则使用”$$” 如果该方法的第一个参数是字符串,则只会替换第一个匹配成功的字符串。

举个栗子

例1:

var reg = /user\d/g;
var str = "user1dduser345";
var s = str.replace(reg,"**");
//s => "**dd**45"

例2:

var reg = /user\d/;
var str = "user1dduser345";
var s = str.replace(reg,"**");
//s => "**dduser345"

例3:

var reg = /user(\d)/g;
var str = "user1dduser345";
var s = str.replace(reg,"$1");
//s => "1dd345"

例4:

var reg = /u(s)er(\d)/g;
var str = "user1dduser345";
var s = str.replace(reg,"$1*$2");
//s => "s*1dds*345"

例5:

var reg = "user";
var str = "user1dduser345";
var s = str.replace(reg,"$$");
//s => "$1dduser345"

附注
以上match(),search(),split(),replace()这些StrinjgObj对象的方法,不会改变StrinjgObj本身的值,而是将结果作为返回值返回。
并且这些方法中的RegExp参数,也可以用字符串参数替换。其返回结果,除了replace()方法,其他的返回结果还是和RegExp参数时的返回结果一样。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值