29.22分钟学会书写正则(2)

李大雷

写在前面的一些废话

没有看过上一篇文章的盆友有福了!

今天!没错!就是现在!我将免费!all f*cking FREE!

免费将上篇文章的链接发出来!

这里是上篇

上回说了怎么写出正则,这次展示下在js中使用正则的场景

正则对象属性

javascript的正则对象有以下几个属性,其中前面三个也叫修饰符(也就是/表达式/两条杠后面的字符,比如上一篇文章出现的 /\bis\b/g 的这个g)。

  • global:是否全文搜索,默认false
  • ignoreCase:是否大小写敏感,默认false,即不忽略大小写
  • multiline:是否多行搜索,默认false
  • lastIndex:当前表达式匹配内容的最后一个字符的下一个位置
  • source:正则表达式的文本字符串,也就是“/表达式/修饰符”中的表达式,var reg=/\bis\b/g; reg.source就是\bis\b

正则相关的方法

js中,RegExp对象有两个内置方法

  • test
  • exec

此外,还有一些String对象的方法也支持正则表达式,它们是

  • search
  • match
  • split
  • replace

test()

test() 方法用于检测一个字符串是否匹配某个模式,返回true或者false.

var reg = /\w/;
reg.test('abc');
//true
reg.test('abc');
//true
reg.test('abc');
//true
reg.test('@#$%')
//false
reg.test('@#$%')
//false
//为什么要多执行几遍呢?你可能会以为楼主lu多了导致老眼昏花多输入了几遍。but NO!多执行几遍是为了和下面作对比。

当我们的正则表达式加上了g修饰符以后,这个方法出现了一些不同

var reg = /\w/g;
reg.test('abc');//true
reg.test('abc');//true
reg.test('abc');//true
reg.test('abc');//false

clipboard.png
为什么会这样呢?因为当我们加上全局搜索这个修饰符后,test()方法会返回结果,并且更新reg对象的属性(lastIndex),他会在上一次lastIndex的位置开始往后查找,而不是从头开始。
所以这个方法建议不要加g,如果你这个人比较倔强,非要加的话,你可以每次都重新初始化一个正则对象,因为它第一次的结果是和没有加g的时候是一样的。
Like this。

var reg = /\w/g;reg.test('abc');//true
//每次都初始化正则对象,把这两行写在一行里比较好复制,因为分开复制一不小心就出现了上面的问题

exec()

exec()方法用于使用正则表达式对字符串执行搜索,并将更新全局RegExp对象的属性以反应匹配结果
如果没有匹配到文本则返回null,否则返回一个结果数组:

  • 数组第一个元素是与正则表达式相匹配的文本
  • 第二个元素是与正则表达式的第一个子表达式(也就是分组1)相匹配的文本(如果有分组1的话)
  • 第三个元素是与正则表达式的第二个子表达式(分组2)相匹配的文本(如果有分组2的话)
  • 除了数组元素和 length 属性之外,exec() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。
var reg = /(\d)(\w)/  //上篇文章已经介绍过分组了,这里的两个括号分别是分组1和分组2
reg.exec('1a2b3c4d5e');

clipboard.png

当我们的正则表达式加上了g修饰符以后,这个方法又出现了一些不同

var reg = /(\d)(\w)/g
reg.exec('1a2b3c4d5e');

还是上图片比较简单~
clipboard.png
这个表现跟test是一个尿性的,即非全局调用(不加g)的时候不会更新lastIndex(lastIndex不生效),全局调用的时候会更新lastIndex

说完了比较复杂的有分组的情况,我们来看看没有分组的情况,言简意赅,你作为这么优秀的一个人,应该能随便看懂吧。

var reg = /\d\w/  
reg.exec('1a2b3c4d5e');

clipboard.png

对于这个方法呢,如果我们只需要查找第一个匹配结果的话可以不加g,如果需要返回所有匹配结果的话,需要循环执行reg.exec(),并且需要加上g。

search()

search()方法用于检索字符串中制定的子字符串或者检索与正则表达式相匹配的子字符串。

方法返回第一个匹配结果的index,查找不到返回-1
search()方法会忽略g标志,总是从字符串的开头进行检索

当我们传入的参数s字符串时,它会转换成正则表达式
var str = "abcd1234"
str.search('1') //4
str.search(/1/) //4
str.search('hello') //-1
str.search(/hello/) //-1

so easy~下一个

match()

非全局调用情况下(不加g):
这个方法类似于exec(),返回值是一毛一样的,one hair one style。
match()方法可在字符串内检索指定的值,或找到一个或多个正则表达式的匹配
如果没有匹配到文本则返回null,否则返回一个结果数组:

  • 数组第一个元素是与正则表达式相匹配的文本
  • 第二个元素是与正则表达式的第一个子表达式(也就是分组1)相匹配的文本(如果有分组1的话)
  • 第三个元素是与正则表达式的第二个子表达式(分组2)相匹配的文本(如果有分组2的话)
  • 除了数组元素和 length 属性之外,match() 方法还返回两个属性。index 属性声明的是匹配文本的第一个字符的位置。input 属性则存放的是被检索的字符串 string。
var str = "1a2b3c4d";
var reg = /(\d)(\w)/;
str.match(reg);

clipboard.png

当我们的正则表达式加上了g修饰符以后,这个方法又出现了一些不同,我为什么要说‘又’

match()方法的返回改变了,变化害...害挺大的,跟前面的exec()和test()方法又有不同

如果没有匹配到文本则返回null,否则返回一个结果数组:

  • 数组元素为与正则表达式匹配的文本
var str = "1a2b3c4d";
var reg = /(\d)(\w)/g;
str.match(reg);

clipboard.png

你有没有发现,即使我已经贴了图,却还是写了代码,为什么?
因为作为一个这么sweet 和 warm的人,我有必要为你节省你自己输入代码的时间,你现在只需要ctrl C 然后ctrl V就可以在浏览器控制疯狂验证我的图片,疯狂测试这些方法!

split()

split()方法用于把一个字符串分割成字符串数组。

//这个也可以输入字符串作为参数,类似于search(),它会转换成正则
var str = "a,b,c,d"
str.split(','); //["a","b","c","d"]
str.split(/,/); //["a","b","c","d"]
//一般情况都是使用字符串居多,比较复杂的情况就可以使用正则
var str ="a1b2c3";
str.split(/\d/); //["a", "b", "c", ""]
//注意:如果字符串最后的子字符串刚好符合参数的正则,那么就会多了一个空的元素,像上面一样

replace()

来了来了,上篇文章中使用最多的replace()终于来了!!!AV8D shout with me! RRRRRRRRrrrrrrrrrrrrrr~EEEEEEE~PPPPP~LLLL~AAAA~CCCCC~EEEEE。

该方法用于在字符串中用一些字符替换另一些字符,或替换一个与正则表达式匹配的子串。

1、 一般用法,这里是一般用法啊,replace('找谁','替换成谁')

该用法的全局与非全局调用的差别是‘替换第一个匹配项’和‘替换所有匹配项’。

举个常用的例子

//这个‘找谁’同样也可以是字符串或者是正则,类似于split(),search()
var str = "hello I am leelei";
str.replace('leelei','岭南吴彦祖'); //"hello I am 岭南吴彦祖"
str.replace(/leelei/,'岭南吴彦祖'); //"hello I am 岭南吴彦祖"

好吧,这个对于你们来说并不常用,可能是只有我在用而已,抱歉。写个你们常用的例子吧

var str = "2018-11-26";
str.replace(/-/,'/');  //"2018/11-26"
//看到没有,这里只替换了一个-
str.replace(/-/g,'/');  //"2018/11/26"
//只有全局调用的时候,才会替换所有的匹配文本

2、 进阶用法,replace('找谁',回调函数),每次匹配替换的时候调用,有4个参数

  • 1、匹配的字符串
  • 2、正则表达式分组内容,没有分组就没有这个这个参数,几个分组就几个该参数
  • 3、匹配项在字符串中的index
  • 4、原字符串,replace()方法不会改变原字符串的哦。
//**当没有分组的时候**
var str ="a5b6c7d8";
//可以根据下面的截图对照上面的参数来理解记忆。
//这里是给每一个匹配的数字+1.
str.replace(/\d/g,function(match,index,origin){
    console.log(match,index,origin);
    return match-0+1;
});

clipboard.png

//**当有分组的时候**
//为字符串中的某些字段更换样式,完整的demo就不写了,大家应该都能看懂吧。
//将第一个分组匹配的内容替换掉
//为什么要分组? 因为我们不想给'个'这个字添加样式,但是又需要用'个'来判断,我们只更改'个'前面的数字的样式,不更改其他数字。
var str = "第1点,这里有4个橘子,5个橙子,9个苹果,我们需要为这几个数量更改样式.";
str.replace(/(\d)个/g,function(match,$1,index,origin){
    console.log(match,$1);
    return "<span style='color:red'>"+$1+"<span>个";
})
//需要注意的是,这个回调函数的return值会覆盖match的值,因此要在return的时候加回'个'字。

clipboard.png
ok~应该足够清楚了吧~

最后

虽然标题是29.22分钟,但是看完两篇文章好像就不止了。
我不管,30分钟内没看完的好好检讨下自己,是不是没有戴眼镜,是不是没睡好觉,看那么慢呢!

如果有建议或者意见,请在评论区指出,非常感谢~

阅读 2.4k

想学唱歌的码农

3.8k 声望
353 粉丝
0 条评论

想学唱歌的码农

3.8k 声望
353 粉丝
宣传栏