正则表达式一直是js里比较难以掌握的点。 看不懂,学不会,记不住。 每次须要用到正则的时候,都须要再去查找资料。 今天花时间把正则的知识点总结下,但愿能在理解的基础上熟练掌握。javascript
正则表达式在字符串处理方面发挥着巨大的做用,掌握了它,就能针对某一特定模式的字符串或者批量对字符串进行处理。 虽然各个编程语言对正则的支持不一样,可是差别并不大。 这里只介绍js语言中正则的使用方法。java
先看一段代码:es6
var formatPrice = function(price){ return price.toString().replace(/\B(?=(\d{3})+$)/g, ','); }
这个formatPrice函数将商品总价转化为每三位以','分割的字符串,这是业务中常遇到的状况。 能够看到,经过使用正则,代码变得至关的简洁。正则表达式
/pattern/flags
, 这就是正则表达式的字面量语法,pattern表示正则表达式的模式,flags为正则表达式的标志。好比: /a[bc]\d{2}$/gi
。
其中模式和标志的知识将会在后面详细介绍。
字面量形式的正则表达式通常使用较多,也推荐你们尽量使用这种形式,简洁易读,符合正常的使用习惯。编程
除了使用字面量外,还可使用构造函数生成正则表达式。 new RegExp(pattern [, flags])
, 好比:var reg= new RegExp('[a-zA-Z]+\\d$', 'gi')
这里构造函数的两个参数,第一个参数能够是字符串(es5及之前)或正则表达式(es6),第二个可选参数为字符串。
当咱们事前不能肯定正则表达式的值时,或者正则依赖第三方输入来动态生成正则时,须要使用这种方式。
这里要注意的一点是:第一个参数为一个字符串时,当咱们使用正则里的特殊字符,好比\d
或\b
等时,须要对\
进行转义,也就是写成\\d
或\\b
的形式,由于\
在字符串里有特殊含义。api
因为正则的使用场景主要是字符串处理,因此字符串类提供了不少方法使用正则表达式。好比:数组
str.replace(regexp|substr, newSubStr|function) str.search(regexp) str.match(regexp) str.split([separator[, limit]])
另外,正则表达式自己也提供了处理字符串的方法,好比:regexObj.exec(str)
regexObj.test(str)
编程语言
这些方法将再后面介绍ide
正则表达式有两种基本字符类型组成:函数
好比: . * + ? () [] {} ^ $ | \
.
- 匹配任意单个字符,行结束符除外\d
- 匹配任意阿拉伯数字,至关于[0-9]\D
- 匹配任意一个不是阿拉伯数字的字符,至关于1, 这里^
用在[]中表示取反的意思。\w
- 匹配任意阿拉伯字母,数字和下划线, 至关于[0-9a-zA-Z_]\W
- 与w相反, 至关于2 \s
- 匹配一个空白符,包括空格符,制表符,换行符,换页符和其余空格字符。\S
- 匹配一个非空白符,与上面相反\t
- 匹配一个水平制表符\r
- 匹配一个回车符\n
- 匹配一个换行符\v
- 匹配一个垂直制表符[abc]
- 又叫字符组,表示匹配集合中的任意一个字符,能够用-
来指定范围[^abc]
- 反义字符组,匹配不是集合中字符的一个字符,能够用-
来指定范围^
- 不使用在[]中时,表示匹配输入开始$
- 匹配输入结尾\b
- 匹配零宽单词边界\B
- 匹配零宽非单词边界,与上面b含义相反。?
- 匹配0次或1次+
- 匹配一次或屡次*
- 匹配0次或屡次{n}
- 匹配n次{m,n}
- 匹配最少m次,最多n次{m,}
- 匹配最少m次举个例子, /\d{3,6}/g
,这样一个正则表达式若是匹配字符串'234955033',是匹配3或4,5,6个数字呢?
js中正则表达式会默认尽量多的匹配,也就是匹配6个数字,即贪婪模式。
非贪婪模式则是让正则表达式尽量少的匹配,也就是只匹配3个数字,正则要使用非贪婪模式,只须要在量词后面加上?
便可。
下面一个例子:
'123456789'.replace(/\d{3,6}/g, 'X') //贪婪模式,结果为'XX' '123456789'.replace(/\d{3,6}?/g, 'X') //非贪婪模式,结果为'XXX'
()
- 将正则表达式分组,以控制量词的做用范围,好比:baron{3}
和 (baron){3}
,两者是有区别的。|
- 表示 或,也能够配合()进行使用,好比: foo|bar 和 fo(o|b)ar有时,咱们在匹配到正则对应的字符串时,还想要使用匹配到的部份内容,这时候可使用$1,$2,$3等符号引用分组捕获的内容。
好比:
'12/03/2017'.replace(/(\d{2})\/(\d{2})\/(\d{4})/, '$3-$1-$2') //输出2017-12-03
这里为了得到年月日的引用,使用()给正则添加了三个分组,而后就能够从前日后分别用$1 $2 $3
代替分组捕获的内容。
全部()里匹配到的内容默认都会被捕获到,有时候,咱们只是想要使用()简单的分组功能,而不须要让正则表达式捕获分组内容,此时,只须要在分组内添加?:
便可,好比:
'12/03/2017'.replace(/(\d{2})\/(?:\d{2})\/(\d{4})/, '$2-$1') //输出2017-12月,第二个分组的内容被忽略。
这里出现了三个新的概念,但其实他们也很简单。
首先,咱们要分清何为前,何为后。
正则匹配字符串是从前日后解析,因此,往字符串尾部方向叫前瞻,往字符串头部方向叫后顾。
js中的正则表达式支持前瞻不支持后顾,因此这里只介绍前瞻。
前瞻通常结合断言使用,其实断言(assert)就至关于给正则加的一个限制条件 -- 表示匹配项不只要符合正则表达式,并且要符合断言给出的条件。
/\d{2}(?=a)/
表示匹配两个数字且后面必须有字母a跟随/\d{2}(?!a)/
表示匹配两个数字且后面没有字母a跟随注意: 断言只是至关于正则的条件,并不会真正的匹配相应的字符。
咱们再来分析开头给出的那段代码:
price.toString().replace(/\B(?=(\d{3})+$)/g, ','); 正则 /\B(?=(\d{3})+$)/g中, \d{3}+$表示以一个或多个三个数字结尾, ?=表示这部分是断言,是正则的条件,即匹配一个零宽的非单词边界,且后面有(3,6,9...)个数字字符的状况
一个正则表达式的实例具备如下一些实例属性
/\d{2}ac/gi
的source属性就是'\d{2}ac'
, 该值不会包含正则两边的//
和标志gi
,也不会像构造函数参数那样对\
进行转义。正则表达式主要有两个实例方法test和exec。
假设regexp表示一个正则的实例,str表示一个字符串,那么
这里要注意的是:应用了全局'g'标志和没有全局'g'标志的同一个模式的正则,对于同一个字符串,两种方法的表现多是不一样的。 由于若是没有全局标识,每次都会从字符串起始位置0开始匹配,而应用了'g',会从上次匹配的结束位的下一位开始匹配。
正则的构造函数RegExp具备一些静态属性,这些属性中保存着最新一次正则匹配的信息。
好比RegExp.$1-$9中,保存着最近一次匹配中分组捕获到的信息。
还有一些其余的静态属性,但平时使用较少,再也不介绍,具体可查阅MDN文档。
字符串的replace是一个很是强大的方法,来看一个例子:
//咱们想把'a1b2c3d4e5'这个字符串替换成字母后数字都加1,变成'a2b3c4d5e6' 'a1b2c3d4e5'.replace(/\d/g, function(match, index, origin){ return parseInt(match) + 1 })
以上就是关于正则的所有总结,精力有限,写的比较乱,见谅。
这里推荐一个很是好的介绍js正则表达式的课程慕课网-javaScript正则表达式
《javascript高级程序设计》
Regexper正则图形化工具
MDN正则表达式