1.符号认识
\d匹配一个数字
\w 匹配一个字母或数字
. 匹配任意字符
\s 匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格A|B可以匹配A或B,所以(J|j)ava(S|s)cript可以匹配'JavaScript'、'Javascript'、'javaScript'或者'javascript' ^表示行的开头,^\d表示必须以数字开头$表示行的结束,\d$表示必须以数字结束
匹配变长的字符:用
*表示任意个字符(包括0个),用+表示至少一个字符,用?表示0个或1个字符,用{n}表示n个字符,用{n,m}表示n-m个字符 来看一个复杂的例子:\d{3}\s+\d{3,8}
2.JavaScript有两种方式创建一个正则表达式
第一种方式是直接通过/正则表达式/写出来,第二种方式是通过new RegExp('正则表达式')创建一个RegExp对象。
var re1 = /ABC\-001/;
var re2 = new RegExp('ABC\\-001');
re1; // /ABC\-001/
re2; // /ABC\-001/
//注意,如果使用第二种写法,因为字符串的转义问题,字符串的两个\\实际上是一个\。
3.切分字符串
正常情况: 'a b c'.split(' '); // ['a', 'b', '', '', 'c']
无法识别连续的空格,用正则表达式试试
'a b c'.split(/\s+/); // ['a', 'b', 'c']
'a,b;; c d'.split(/[\s\,\;]+/); // ['a', 'b', 'c', 'd']
4.分组
正则表达式还有提取子串的强大功能。用()表示的就是要提取的分组(Group)eg:
-
^(\d{3})\-(\d{3,8})$分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码:
var re = /^(\d{3})-(\d{3,8})$/;
re.exec('010-12345');
// ["010-12345", "010", "12345", index: 0, input: "010-12345", groups: undefined]
re.exec('010 12345'); // null
5.贪婪匹配
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。举例如下,匹配出数字后面的0:
var re = /^(\d+)(0*)$/;
re.exec('102300');
/*
["102300", "102300", "", index: 0, input: "102300", groups: undefined]
由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
*/
让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:
var re = /^(\d+?)(0*)$/;
re.exec('102300');
//["102300", "1023", "00", index: 0, input: "102300", groups: undefined]
6.全局搜索
var r1 = /正则表达式/g;
// 等价于:
var r2 = new RegExp('正则表达式', 'g');
全局匹配可以多次执行exec()方法来搜索一个匹配的字符串。当我们指定g标志后,每次运行exec(),正则表达式本身会更新lastIndex属性,表示上次匹配到的最后索引:
var s = 'JavaScript, VBScript, JScript and ECMAScript';
var re=/[a-zA-Z]+Script/g;
// 使用全局匹配:
re.exec(s); // ['JavaScript']
re.lastIndex; // 10
re.exec(s); // ['VBScript']
re.lastIndex; // 20
re.exec(s); // ['JScript']
re.lastIndex; // 29
re.exec(s); // ['ECMAScript']
re.lastIndex; // 44
re.exec(s); // null,直到结束仍没有匹配到