字符串是编程时涉及到的最多的一种数据结构,对字符串进行操作的需求几乎无处不在。比如判断一个字符串是否是合法的Email地址,虽然可以编程提取@
前后的子串,再分别判断是否是单词和域名,但这样做不但麻烦,而且代码难以复用。
'use strict';
验证Email地址的正则表达式
var re1 = /^[0-9a-zA-Z\.]+@[0-9a-z]+\.[0-9a-z]+$/;
验证并提取出带名字的Email地址的正则表达式
var re2 = =/^\<([\w\s\w]+)\>\s+([0-9a-zA-Z\.]+@[0-9a-zA-Z]+\.[a-zA-Z]+)$/;
测试re1:
var
i,
success = true,
should_pass = ['someone@gmail.com', 'bill.gates@microsoft.com', 'tom@voyager.org', 'bob2015@163.com'],
should_fail = ['test#gmail.com', 'bill@microsoft', 'bill%gates@ms.com', '@voyager.org'];
for (i = 0; i < should_pass.length; i++) {
if (!re.test(should_pass[i])) {
console.log('测试失败: ' + should_pass[i]);
success = false;
break;
}
}
for (i = 0; i < should_fail.length; i++) {
if (re.test(should_fail[i])) {
console.log('测试失败: ' + should_fail[i]);
success = false;
break;
}
}
if (success) {
console.log('测试通过!');
}
测试re2:
var r = re.exec('<Tom Paris> tom@voyager.org');
if (r === null || r.toString() !== ['<Tom Paris> tom@voyager.org', 'Tom Paris', 'tom@voyager.org'].toString()) {
console.log('测试失败!');
}
else {
console.log('测试成功!');
}
正则表达式是一种用来匹配字符串的强有力的武器。它的设计思想是用一种描述性的语言来给字符串定义一个规则,凡是符合规则的字符串,我们就认为它“匹配”了,否则,该字符串就是不合法的。
正则表达式也是用字符串表示的,所以,要首先了解如何用字符来描述字符。
创建正则表达式对象的语法如下:
- var patt=new RegExp(pattern,modifiers);
- var patt=/pattern/modifiers;
- pattern(模式) 描述了表达式的模式
- modifiers(修饰符) 用于指定全局匹配、区分大小写的匹配和多行匹配
var r11 = /test/g;
// 等价于:
var r12 = new RegExp('test', 'g');
var r21 = /^(\d+)(0*)$/;
// 等价于:
var r22 = new RegExp('^(\\d+)(0*)$'); //注意\d是正则语法,\d在字符串里面就是显示的是d,并不会显示\,需要使用转义字符
在正则表达式中,如果直接给出字符,就是精确匹配。元字符指的是拥有特殊含义的字符:用\d
可以匹配一个数字,\w
可以匹配一个字母或数字, .
可以匹配任意字符,如果要匹配点号本身,则需要转义\.。
要匹配变长的字符,在正则表达式中,就是量词。用*
表示任意个字符(包括0个),用+
表示至少一个字符,用?
表示0个或1个字符,用{n}
表示n个字符,用{n,m}
表示至少n次,最多m次匹配。
'00\d'可以匹配'007',但无法匹配'00A';
'\d\d\d'可以匹配'010';
'\w\w'可以匹配'js';
'js.'可以匹配'jsp'、'jss'、'js!'等等。
\d{3}\s+\d{3,8}
从左到右解读一下:
\d{3}表示匹配3个数字,例如'010';
\s可以匹配一个空格(也包括Tab等空白符),所以\s+表示至少有一个空格,例如匹配' ','\t\t'等;
\d{3,8}表示3-8个数字,例如'1234567'。
复杂的匹配方式:
如果要匹配'010-12345'
这样的号码,所以,上面的正则是\d{3}-\d{3,8}。
但是,仍然无法匹配'010 - 12345'
,因为带有空格。所以我们需要更复杂的匹配方式。
要做更精确地匹配,可以用方括号[]
表示查找范围。使用小括号()表示要匹配的整体字符串即分组。使用大括号{}表示量词。A|B表示可以匹配单个字符A或B,那么(red|green|blue)表示匹配整体red字符串或者green或者blue。
[0-9a-zA-Z\_]可以匹配一个数字、字母或者下划线;
[0-9a-zA-Z\_]+可以匹配至少由一个数字、字母或者下划线组成的字符串,比如'a100','0_Z','js2015'等等;
[a-zA-Z\_\$][0-9a-zA-Z\_\$]*可以匹配由字母或下划线、$开头,后接任意个由一个数字、字母或者下划线、$组成的字符串,也就是JavaScript允许的变量名;
[a-zA-Z\_\$][0-9a-zA-Z\_\$]{0, 19}更精确地限制了变量的长度是1-20个字符(前面1个字符+后面最多19个字符)。
(J|j)ava(S|s)cript可以匹配'JavaScript'、'Javascript'、'javaScript'或者'javascript'因为(red|blue|green) 查找任何指定的选项。
正则表达式对象的方法:
test() 方法是一个正则表达式方法:它通过模式来搜索字符串,用于测试给定的字符串是否符合条件然后根据结果返回 true 或 false。
var patt = /e/;
patt.test("The best things in life are free!"); //返回true
var re = /^\d{3}\-\d{3,8}$/;
re.test('010-12345'); // true
re.test('010-1234x'); // false
re.test('010 12345'); // false
不必首先把正则表达式放入变量中,可缩短为一行
/e/.test("The best things in life are free!"); // true
/^\d{3}\-\d{3,8}$/.test('010-12345'); // true
exec() 方法是一个正则表达式方法:它通过指定的模式(pattern)搜索字符串,并返回已找到的文本。注意:exec()
方法在匹配成功后,会返回一个Array
,第一个元素是正则表达式匹配到的整个字符串,后面的字符串表示匹配成功的子串(如果使用了分组符号)。exec()
方法在匹配失败时返回null
。
var re = /^(\d{3})-(\d{3,8})$/; // 分别定义了两个组,可以直接从匹配的字符串中提取出区号和本地号码
re.exec('010-12345'); // ['010-12345', '010', '12345'],使用分组符号会返回分组字符串
/^\d{3}-\d{3,8}$/.exec('010-12345'); // ['010-123456']
re.exec('010 12345'); // null
正则匹配默认是贪婪匹配,也就是匹配尽可能多的字符。
var re = /^(\d+)(0*)$/;
re.exec('102300'); // ['102300', '102300', ''] 由于\d+采用贪婪匹配,直接把后面的0全部匹配了,结果0*只能匹配空字符串了。
var re = /^(\d+?)(0*)$/; // 必须让\d+采用非贪婪匹配(也就是尽可能少匹配),才能把后面的0匹配出来,加个?就可以让\d+采用非贪婪匹配:
re.exec('102300'); // ['102300', '1023', '00']
上述说明了RegExp对象的属性和方法。一般情况下,正则表达式常用于字符串的函数中用来匹配,那么支持支持正则表达式的字符串方法有:通常搭配使用修饰符g