正则表达式(regular expression)用来按照“给定模式”匹配文本。比如,正则表达式给出一个 Email 地址的模式,然后用它来确定一个字符串是否为 Email 地址。
新建正则表达式有两种方法。一种是使用字面量,以斜杠表示开始和结束
var regex = /xyz/;
另一种是使用RegExp
构造函数
var regex = new RegExp('xyz');
正则执行方法
正则的执行的方法主要有两种,一种是 test()
方法,另一种是 exec()
方法
test()
正则对象的test
方法返回一个布尔值,表示当前模式是否能匹配参数字符串
/it/.test('itbaizhan') // true
如果正则模式是一个空字符串,则匹配所有字符串
new RegExp('').test('abc')
exec()
正则对象的exec
方法,用来返回匹配结果。如果发现匹配,就返回一个数组,成员是匹配成功的子字符串,否则返回null
。
var str = 'itbaizhan'; var reg1 = /it/; var reg2 = /sxt/; console.log(reg1.exec(str)); console.log(reg2.exec(str));
字符串方法之中,有4种与正则表达式有关
1
String.prototype.match()
返回一个数组,成员是所有匹配的子字符串
2String.prototype.search()
按照给定的正则表达式进行搜索,返回一个整数,表示匹配开始的位置
3String.prototype.replace()
按照给定的正则表达式进行替换,返回替换后的字符串
4String.prototype.split()
按照给定规则进行字符串分割,返回一个数组,包含分割后的各个成员
String.prototype.match()
字符串实例对象的match
方法对字符串进行正则匹配,返回匹配结果
var str = 'itbaizhan'; var reg1 = /baizhan/; var reg2 = /sxt/; console.log(str.match(reg1)); console.log(str.match(reg2));
String.prototype.search()
字符串对象的search
方法,返回第一个满足条件的匹配结果在整个字符串中的位置。如果没有任何匹配,则返回-1
。
"itbaizhan".search(/it/); // 0
String.prototype.replace()
字符串对象的replace
方法可以替换匹配的值。它接受两个参数,第一个是正则表达式,表示搜索模式,第二个是替换的内容
"itbaizhan".replace(/it/,"sxt")
String.prototype.split()
字符串对象的split
方法按照正则规则分割字符串,返回一个由分割后的各个部分组成的数组。
该方法接受两个参数,第一个参数是正则表达式,表示分隔规则,第二个参数是返回数组的最大成员数。
"it,sxt,itbaizhan".split(/,/) "it,sxt,itbaizhan".split(/,/,2)
字面量字符
大部分字符在正则表达式中,就是字面的含义,比如/a/
匹配a,/b/
匹配b
。如果在正则表达式之中,某个字符只表示它字面的含义(就像前面的a
和b
),那么它们就叫做“字面量字符”
/it/.test('itbaizhan')
元字符
除了字面量字符以外,还有一部分字符有特殊含义,不代表字面的意思。它们叫做“元字符”(metacharacters),主要有以下几个
1 点字符(.)
2 位置字符
3 选择符(|)
点字符(.)
点字符(.)
匹配除回车(\r)
、换行(\n)
、行分隔符(\u2028)
和段分隔符(\u2029)
以外的所有字符。
/c.t/
c.t
匹配c
和t
之间包含任意一个字符的情况,只要这三个字符在同一行,比如cat、c2t、c-t
等等,但是不匹配coot
位置字符
位置字符用来提示字符所处的位置,主要有两个字符
^ 表示字符串的开始位置
$ 表示字符串的结束位置
/^it/.test('itbaizhan'); /it$/.test('learn it'); /^it$/.test('it');
选择符(|)
竖线符号(|)
在正则表达式中表示“或关系”(OR)
,即cat|dog
表示匹配cat
或dog
/it|sxt/.test('itbaizhan'); /it|sxt/.test('sxtbaizhan');
正则表达式中那些有特殊含义的元字符,如果要匹配它们本身,就需要在它们前面要加上反斜杠。比如要匹配+
,就要写成 \+
/1+1/.test('1+1'); // false /1\+1/.test('1+1'); // true
正则表达式中,需要反斜杠转义的,一共有12个字符: ^、.、[、$、(、)、|、*、+、?、{和\\
温馨提示
使用new
关键字生成正则对象,转义需要使用两个斜杠,因为字符串内部会先转义一次
new RegExp('1\+1').test('1+1') // false new RegExp('1\\+1').test('1+1') // true
字符类表示有一系列字符可供选择,只要匹配其中一个就可以了。所有可供选择的字符都放在方括号内,比如 [xyz]
表示x、y、z
之中任选一个匹配
/[abc]/.test('hello world'); // false /[abc]/.test('apple'); // true
字符类分为两类
1 脱字符(^)
2 连字符(-)
脱字符(^)
如果方括号内的第一个字符是[^]
,则表示除了字符类之中的字符,其他字符都可以匹配。比如, [^xyz]
表示除了x、y、z之外都可以匹配
/[^abc]/.test('hello world'); // true /[^abc]/.test('aabbcc'); // false
温馨提示
/[^abc]/.test('aabbcc')
内容必须全部都为abc才是false,否则为true
连字符(-)
某些情况下,对于连续序列的字符,连字符(-)
用来提供简写形式,表示字符的连续范围。比如,[abc]
可以写成[a-c]
,[0123456789]
可以写成[0-9]
,同理[A-Z]
表示26个大写字母
/a-z/.test('b'); // false /[a-z]/.test('b'); // true
以下都是合法的字符类简写形式
[0-9.,] [0-9a-fA-F] [a-zA-Z0-9-] [1-31]
预定义模式
预定义模式指的是某些常见模式的简写方式
\d
匹配0-9之间的任一数字,相当于[0-9]
。
\D
匹配所有0-9以外的字符,相当于[^0-9]
。
\w
匹配任意的字母、数字和下划线,相当于[A-Za-z0-9_]
。
\W
除所有字母、数字和下划线以外的字符,相当于[^A-Za-z0-9_]
。
\s
匹配空格(包括换行符、制表符、空格符等),相等于[\t\r\n\v\f]
。
\S
匹配非空格的字符,相当于[^ \t\r\n\v\f]
。
\b
匹配词的边界。
\B
匹配非词边界,即在词的内部。
/\d/.test(100); // true /\d/.test("hello"); // false /\D/.test(100); // false /\D/.test("hello"); // true /\w/.test("itbaizhan"); // true /\w/.test("&&"); // false /\W/.test("itbaizhan"); // false /\W/.test("&&"); // true /\s/.test("\t\r"); // true /\s/.test("hello"); // false /\S/.test("\t\r"); // false /\S/.test("hello"); // true /\bhello/.test("hi,hello"); // true /\bhello/.test("helloworld"); // true /\Bhello/.test("hi,hello"); // false /\Bhello/.test("helloworld"); // false
重复类
模式的精确匹配次数,使用大括号({})
表示。{n}
表示恰好重复n
次,{n,}
表示至少重复n
次,{n,m}
表示重复不少于n
次,不多于m
次。
/lo{2}k/.test('look'); // true /lo{2,5}k/.test('looook'); // true
量词符
量词符用来设定某个模式出现的次数
?
问号表示某个模式出现0次或1次,等同于{0, 1}
。
*
星号表示某个模式出现0次或多次,等同于{0,}
。
+
加号表示某个模式出现1次或多次,等同于{1,}
。
// t 出现0次或1次 /t?est/.test('test'); // true /t?est/.test('est'); // true /t?est/.test('ttttest'); // true 特别注意 /^t?est/.test('ttttest'); // false // t 出现1次或多次 /t+est/.test('test'); // true /t+est/.test('ttest'); // true /t+est/.test('est'); // false // t 出现0次或多次 /t*est/.test('test'); // true /t*est/.test('ttest'); // true /t*est/.test('tttest'); // true /t*est/.test('est'); // true
贪婪模式
贪婪模式默认情况下量词符 +
和 *
都是最大可能匹配,即匹配直到下一个字符不满足匹配规则为止。
"aaa".match(/a+/); // ["aaa"] /a+/.exec("aaa"); // ["aaa"]
模式是/a+/
,表示匹配1个a或多个a,那么到底会匹配几个a呢?因为默认是贪婪模式,会一直匹配到字符a不出现为止,所以匹配结果是3个a
如果想将贪婪模式改为非贪婪模式,可以在量词符后面加一个问号。
"aaa".match(/a+?/); // ["a"] /a+?/.exec("aaa"); // ["a"]
模式结尾添加了一个问号/a+?/
,这时就改为非贪婪模式,一旦条件满足,就不再往下匹配。
修饰符
修饰符(modifier)表示模式的附加规则,放在正则模式的最尾部
修饰符有三个:
1 g修饰符 2 i修饰符 3 m修饰符
g 修饰符
默认情况下,第一次匹配成功后,正则对象就停止向下匹配了。g修饰符表示全局匹(global),加上它以后,正则对象将匹配全部符合条件的结果,主要用于搜索和替换。
"abba".replace(/b/,"t"); // atba "abba".replace(/b/g,"t"); // atta
还有一个使用特点:多次匹配问题
var regex = /b/; var str = 'abba'; regex.test(str); // true regex.test(str); // true regex.test(str); // true
正则模式不含g修饰符,每次都是从字符串头部开始匹配。所以,连续做了三次匹配,都返回 true
var regex = /b/g; var str = 'abba'; regex.test(str); // true regex.test(str); // true regex.test(str); // false
正则模式含有g修饰符,每次都是从上一次匹配成功处,开始向后匹配。因为字符串abba只有两个b,所以前两次匹配结果为true,第三次匹配结果为false
i 修饰符
默认情况下,正则对象区分字母的大小写,加上i
修饰符以后表示忽略大小写(ignorecase)
/abc/.test('ABC'); // false /abc/i.test('ABC'); // true
m修饰符
m 修饰符表示多行模式(multiline),会修改 ^
和 $
的行为。默认情况下(即不加 m 修饰符时), ^
和 $
匹配字符串的开始处和结尾处,加上 m 修饰符以后, ^
和 $
还会匹配行首和行尾,即 ^
和 $
会识别换行符( \n
)
/world$/.test('hello world\n'); // false /world$/m.test('hello world\n'); // true
修饰符组合
常见的就是i
和g
的组合
"ABBA".replace(/b/ig,"t"); // AttA
组匹配
正则表达式的括号表示分组匹配,括号中的模式可以用来匹配分组的内容
/fred+/.test('fredd'); // true /(fred)+/.test('fredfred'); // true
第一个模式没有括号,结果+
只表示重复字母d
第二个模式有括号,结果+
就表示匹配fred
这个词
身份证正则验证
1 老版本:15位全数字组成
2 新版本:18位,前17位全数字,第十八位数字或者x
/(^\d{15}$)|(^\d{18}$)|(^\d{17}(\d|x)$)/i
手机号
/^1(3|4|5|6|7|8|9)\d{9}$/
大部分的正则表达式是不需要我们自己编写的,我们需要做的是能读懂即可
推荐正则表达式在线工具:https://tool.oschina.net/regex/