JavaScript正则表达式

来源:互联网 发布:windows xp msdn iso 编辑:程序博客网 时间:2024/05/29 11:27

原文链接:https://segmentfault.com/a/1190000007602848

JS中,RegExp对象表示正则表达式,它是对字符串执行模式匹配的强大工具。

基本语法

方法1:

/pattern/attributes

方法2:

new RegExp(pattern, attributes);

两种方法中的attributes成为修饰符,可能是g,i,m三种不同的取值

g:globel,表示执行全局匹配,而非在找到第一个匹配后停止。i:执行不区分大小写的匹配。m:执行多行匹配。

方括号

方括号内可以包含一些列字符,可以匹配方括号内的任意字符,同时可以通过符号^来定义否定字符类。

[abc]:查找方括号种的任意一个字符[^abc]:查找不在方括号内的任意一个字符[0-9]:查找0-9种人一一个数字(red | blue | green):查找小括号种的任意一项,|是或者的意思

元字符

.   查找任意的单个字符,除换行符和其他Unicode行终止符之外\w  查找字母数字和下划线 ,等价于[a-zA-Z0-9_]\W  查找除字母数字下划线之外的字符,等价于[^a-zA-Z0-9_]\d  查找数字字符,等价于[0-9]\D  查找非数字字符,等价于[^0-9]\s  匹配任何空白字符,包括空格,制表符,换行符等等。等价于[\f\n\r\t\v]\S  匹配任何非空白字符,等价于[^\f\n\r\t\v]\b  查找一个单词边界,也就是指单词和空格间的位置,比如er\b可以匹配"never"中的"er",但是不能匹配"verb"中的"er"\B  查找非单词边界,er\B能匹配"ver"中的"er",但不能匹配"never"中的"er"\0  查找空字符("")\n  查找换行符\r  查找回车符\f  查找换页符\t  查找制表符\v  查找垂直制表符

量词

n+      匹配任何至少包含一个n的字符串,等价于n{1,}n*      匹配零个或者多个n的字符串,等价于n{0,}n?      匹配零个或者1个n的字符串,等价于n{0,1}n{x}    匹配包含x个n的序列字符串n{x,y}  匹配至少x个,最多y个n的字符串n{x,}   匹配至少x个n的字符串n$     匹配以n结尾的字符串^n      匹配以n开头的字符串

正则表达式中,特殊字符需要转译字符

正则表达式中,特殊字符都有它们特殊的含义,所以当我们要匹配这些特殊字符本身的时候,需要对字符进行转译,即在字符前面加上\,这些特殊字符包括:$ ^ * + . [ ? { | ( ) \

支持正则表达式的方法

RegExp对象方法:
1、test:

RegExpObject.test(str)

参数是要检测的字符串,如果匹配,该表达式返回true,否则返回false。

2、exec:

RegExpObject.exec(str)

函数将会反悔一个数组,返回字符串中所有匹配的结果。如果未找到匹配,则返回null。

支持正则表达式的string对象的方法

1、search:

stringObject.search(regexp)

返回在string中第一个可以和regexp对象匹配的字符串的起始位置,如果没有找到任何可以匹配的字符串,则返回-1.

2、match:

stringObject.match(regexp)

返回匹配成功的数组,如果没有找到匹配,则返回null。

3、replace:

stringObject.replace(regexp/substr,replacement);

该方法用于在字符串中用另一些字符替换原字符,其中,参数replacement可以是替换的文本或者是生成替换文本的函数。

如果replacement是字符串,那么匹配向将会被这个字符串代替。需要注意的是,在replacement中,$字符具有特殊的含义,利用这些,我们可以将从模式匹配得到的字符串用于替换

$1、$2...、$99 与 regexp 中的第 1 到第 99 个子表达式相匹配的文本。$& 与 regexp 相匹配的子串。$` 位于匹配子串左侧的文本。$' 位于匹配子串右侧的文本。$$    表示美元符号$。

例子:

var name = "longen    ,yunxi";var s4 = name.replace(/(\w+)\s*,\s*(\w+)/,"$2 $1");console.log(s4); // "yunxi,longen"console.log('hello world'.replace(/w/g, '$&')) //hello worldconsole.log('hello world'.replace(/w/g, '$$')) //hello $orldconsole.log('hello world'.replace(/w/g, '$`')) //hello hello orldconsole.log('hello world'.replace(/w/g, "$'")) //hello orldorld

另外,如果regexp具有全局标志,那么replace方法会将所有匹配的字符串替换,否则,只替换第一个匹配子串。

4、split

stringObject.split(separator,howmany)

其中,参数:
1.separator[必填],字符串或正则表达式,该参数指定的地方分割stringObject;
2.howmany[可选] 该参数指定返回的数组的最大长度,如果设置了该参数,返回的子字符串不会多于这个参数指定的数组。如果没有设置该参数的话,整个字符串都会被分割,不考虑他的长度。
返回值:一个字符串数组。该数组通过在separator指定的边界处将字符串stringObject分割成子字符串。

贪婪模式与非贪婪模式

贪婪模式在整个表达式匹配成功的情况下尽可能多的匹配,非贪婪模式则在整个表达式匹配成功的前提下,尽可能少的匹配。

一些常见的修饰贪婪模式的量词:

{x,y}{x,},?,*和+

非贪婪模式就是在贪婪模式的量词后加一个?

{x,y}?,{x,}?,??,*?,和+?

例子:

//贪婪模式,尽可能多的匹配console.log('0123456789'.replace(/\d{3,6}/,"*")) //*6789//非贪婪模式,尽可能少的匹配console.log('0123456789'.replace(/\d{3,6}?/,"*")) //*3456789

分组

//不分组,量词仅作用到最后一个字符(c)console.log(/abc{2}/.test('abcabc')); // falseconsole.log(/abc{2}/.test('abcc')); //true//分组,量词作用于整个括号里的子表达式console.log(/(abc){2}/.test('abcabc')); // trueconsole.log(/(abc){2}/.test('abcc')); //false

反向引用

当一个正则表达式被分组后,每一个分组将会自动被赋予一个组号,从左到右依次为:$1 $2 …

//格式化日期var reg = /^(\d{4})[/-](\d{2})[/-](\d{2})$/console.log('2016/11/18'.replace(reg, '$1年$2月$3日')) //2016年11月18日console.log('2016-11-18'.replace(reg, '$1年$2月$3日')) //2016年11月18日console.log('2016-11-18'.replace(reg, '$1$2$3')) //20161118

非捕获性分组

不是所有的分组都能创建反向引用,有一种分组叫做非捕获性分组,非捕获性分组用(?:pattern)表示,一些只需要分组匹配,但是并不需要得到各个分组匹配的结果时,使用非捕获性分组可以提高匹配速度。

非捕获分组的含义我们可以理解为如下:子表达式可以作为被整体修饰但是子表达式匹配的结果不会被存储;如下:

var reg = /(?:\d{4})-(\d{2})-(\d{2})/var date = '2012-12-21'reg.test(date)RegExp.$1  // 12RegExp.$2  // 21

这里,(?:d{4})分组不会捕获任何字符串,所以$1为(d{2})捕获的字符串。

零宽断言

零宽断言就是下结论,例如字符串是ab,正则表达式为:a(?=b),匹配a并且a的右边是b,得到的结果是a,断言不会在匹配的内容当中,如果是a(?=c),则匹配不到任何内容,因为匹配a以后向右看并不是c。另外,零宽断言分两种:前瞻(Lookahead)和后顾(Lookbehind);但JavaScript只支持前瞻。

前瞻表达式的语法如下:

m(?=n)  匹配后面紧接n的字符串mm(?!n)  匹配后面没有紧接n的字符串m