一篇文章带你玩转正则表达式
读这篇文章之前你需要掌握基本的JavaScript知识,并且有安静舒适的环境与宽裕的时间,文章有点长,你可以选择备好coffee或茶来慢慢学习。 概念和语法REGEXP对象 JavaScript 通过内置对象RegExp支持正则表达式,有两种方法实例化RegExp对象
字面量
没有g: var reg = /bisb/; //只替换第一项 'He is a boy. This is a dog. Where is she?'.replace(reg,'IS'); "He IS a boy. This is a dog. Where is she?" 有g: var reg = /bisb/g; //替换了所有的 'He is a boy. This is a dog. Where is she?'.replace(reg,'IS'); "He IS a boy. This IS a dog. Where IS she?" 构造函数
修饰符
//未忽略大小写 'He is a boy. Is he?'.replace(/bisb/g,'0'); "He 0 a boy. Is he?" //忽略大小写 'He is a boy. Is he?'.replace(/bisb/gi,'0'); "He 0 a boy. 0 he?" 元字符·正则表达式由两种基本字符类型组成:
·元字符是在正则表达式中有特殊含义的非字母字符 `· * + ? $ ^ . / () {} []` 字符类我们可以使用元字符 [] 来构建一个简单的类 'a1b2c3d4'.replace(/[abc]/g,'X') "X1X2X3d4" 字符类取反使用元字符^创建 反向类/负向类 'a1b2c3d4'.replace(/[^abc]/g,'X') "aXbXcXXX" 范围类正则表达式还提供了 范围类 'a1b2d3x4z9'.replace(/[a-z]/g,'Q') "Q1Q2Q3Q4Q9" 在[]组成的类内部是可以连写的[a-zA-Z] (one of) 'a1b2d3x4z9AJHGK'.replace(/[a-zA-Z]/g,'Q') "Q1Q2Q3Q4Q9QQQQQ" 中划线:如果是在里面 如[a-z],就表示范围的意思,如果想匹配中划线,在后面加 '2016-09-12'.replace(/[0-9-]/g,'A') "AAAAAAAAAA" 预定义类正则表达式提供 预定义类 来匹配常见的字符类
边界正则表达式还提供了几个常用的边界匹配字符 ^ 以xxx开始 $ 以xxx结束 b 单词边界 B 非单词边界 '@123@abc@'.replace(/@./g,'Q') "Q23Qbc@" '@123@abc@'.replace(/^@./g,'Q') "Q23@abc@" '@123@abc@'.replace(/.@/g,'Q') "@12QabQ" '@123@abc@'.replace(/.@$/g,'Q') "@123@abQ" 量词我们希望匹配一个连续出现20次数字的字符串
贪婪模式
//尽可能多的匹配 '12345678'.replace(/d{3,6}/g,'X') "X78" 非贪婪模式让正则表达式尽可能少的匹配,也就是说一旦成功匹配不再继续尝试就是非贪婪模式 //在量词后加上?即可 如下面的为3个一组 '12345678'.replace(/d{3,6}?/g,'X') "XX78" 分组匹配字符串Byron连续出现3次的场景 //错误的 'a1b2c3d4'.replace(/[a-z]d{3}/g,'X') "a1b2c3d4" //正确的 'a1b2c3d4'.replace(/([a-z]d){3}/g,'X') "Xd4" 或使用 | 可以达到或的效果 //示例一 'ByronCasper'.replace(/Byron|Casper/g,'X') "XX" //示例二(分组和或配合使用) 'ByronsperByrCasper'.replace(/Byr(on|Ca)sper/g,'X') "XX" 反向引用2016-08-12 => 08/12/2016 //分组捕获 '2016-08-12'.replace(/(d{4})-(d{2})-(d{2})/g,'$1') "2016" '2016-08-12'.replace(/(d{4})-(d{2})-(d{2})/g,'$2/$3/$1') "08/12/2016" 忽略分组不希望捕获某些分组,只需要在分组内加上?:就可以 前瞻正则表达式从文本头部向尾部开始解析,文本尾部方向,称为“前” 正向前瞻 exp(?=assert) //单词后面是数字 'a2*3'.replace(/w(?=d)/g,'X') "X2*3" 'a2*34v8'.replace(/w(?=d)/g,'X') "X2*X4X8" //单词后面不是数字 'a2*34vv'.replace(/w(?!d)/g,'X') "aX*3XXX" 对象属性对象属性是只读的
test和exec方法RegExp.prototype.test(str) var reg1 = /w/; reg1.test('a') true reg1.test('$') false 但是如果这样: var reg2 = /w/g; //第一次 reg1.test('ab') true //第二次 reg1.test('ab') true //第三次 reg1.test('ab') false 这是lastIndex在作怪! 解决方法: (/w/g).test('ab') 这样就能每次都是true,但是会产生内存开销,不采用! ②如果想用test本意的话,不用加g,只需检测有没有就可以了。 RegExp.prototype.exec(str) 如果没有匹配的文本则返回null,否则返回一个结果数组: 非全局调用 调用非全局的RegExp对象的exec()时,返回数组 var reg3 = /d(w)(w)d/; var reg4 = /d(w)(w)d/g; var ts = '$1az2bb3cy4dd5ee'; var ret = reg3.exec(ts); //在非全局下 lastIndex失效 console.log(reg3.lastIndex + 't' + ret.index + 't' + ret.toString()); console.log(reg3.lastIndex + 't' + ret.index + 't' + ret.toString()); while(ret = reg4.exec(ts)){ console.log(reg4.lastIndex + 't' + ret.index + 't' + ret.toString()); } //结果: "0 1 1az2,a,z" "0 1 1az2,z" "5 1 1az2,z" "11 7 3cy4,c,y" 字符串对象方法Stringl.protatype.search(reg) String.prototype.match(reg) 返回数组的第一个元素存放的是匹配文本,而其余的元素存放的是与正则表达式的子表达式匹配的文本
var reg3 = /d(w)d/; var reg4 = /d(w)d/g; var ts = '$1a2b3c4d5e'; var ret = ts.match(reg3); console.log(ret); console.log(ret.index + 't' + reg3.lastIndex); //结果 ["1a2","a"] "1 0" 全局调用 ret = ts.match(reg4); console.log(ret); console.log(ret.index + 't' + reg3.lastIndex); //结果 ["1a2","3c4"] "undefined 0" String.prototype.split(reg) String.prototype.replace
function参数含义 function会在每次匹配替换的时候调用,有四个参数 ①匹配字符串 ②正则表达式分组内容,没有分组则没有该参数 ③匹配项在字符串中的index ④原字符串 'a1b2c3d4e5'.replace(/d/g,function(match,index,origin){ console.log(index); return parseInt(match) + 1; }); //结果 1 3 5 7 9 "a2b3c4d5e6" 'a1b2c3d4e5'.replace(/(d)(w)(d)/g,group1,group2,group3,origin){ console.log(match); return group1 + group3; }); //结果 "1b2" "3d4" "a12c34e5" 希望能对你有所帮助,更好的运用正则来解决问题!
博客地址:(http://fehey.com/2016/08/12/r... ) 欢迎前端小伙伴交流~ (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |