正则表达式是一个描述字符模式的对象。JavaScript的RegExp类表示正则表达式。
一、正则表达式的定义
1.构造函数的方式
new RegExp() :第一个参数:正则表达式 第二个参数:标志位
var re1 = new RegExp(i,"g"); //g : 表示全局匹配
2.字面量的方式
/正则/标志位
3、直接量字符
字符 | 匹配 |
\o | NUL字符(\u0000) |
\t | 制表符(\u0009) |
\n | 换行符(\u000A) |
\v | 垂直制表符(\u000B) |
\f | 换页符(\u000C) |
\r | 回车符(\u000D) |
\xnn | 由十六进制数nn指定的拉丁字符,例如,\x0A等价于\n |
\uxxxx | 由十六进制数xxxx指定的Unicode字符,例如,\u0009等价于\t |
\cX | 控制字符^X,例如,\cJ等价于换行符\n |
4、转义字符类
[]表示的也属于字符类。
\s | 表示空白 |
\S | 表示非空白 |
\d | 表示数字,相当于[0-9] |
\D | 表示非数字,相当于[^0-9] |
\w | 表示字母、数字、下划线,相当于[a-zA-Z0-9_] |
\W | 表示非(字母、数字、下划线),相当于[^a-zA-Z0-9_] |
\b | 表示单词边界,[\b]匹配的是退格符 |
5、元字符
{ } [ ] () * + ? ^ $ . | \
{ } 表示括号前的一个或一组字符连续出现的次数
{m} | 表示括号前的一个或一组字符只能连续出现m次 |
{m,} | 表示括号前的一个或一组字符连续出现m至无限次 |
{m,n} | 表示括号前的一个或一组字符连续出现m 至 n 次 |
[ ]:表示方括号内的任意字符
( ):表示组,而且可以记住和这个组合相匹配的字符串以供此后的引用使用
(?: ):只组合,把项组合到单元,但不记忆与该组相匹配的字符
* : 表示星号前面一个或一组字符连续出现 0 至 无限次,相当于{0,}
+ : 表示加号前面一个或一组字符连续出现 1 至 无限次,相当于{1,}
? : 表示问号前面一个或一组字符连续出现 0 至 1次,相当于{0,1}
^ : 用在正则表达式的开头位置,叫做定头(断头),表示字符串开头必须是指定的字符
用在[ ]中的开头位置,叫做取反
$ : 叫做定尾(断尾),表示字符串结尾必须是指定的字符
(?=p):零宽正向先行断言,要求接下来的字符都与p匹配,但不能包括匹配p的那些字符。如:
/[jJ]ava([sS]cript)?(?=\:)/这个正则只能匹配“JavaScript: The Definitive Guide”中的“JavaScript”,不能匹配“Java in a Nutshell”中的“Java”,因为它后面没有冒号
(?!p):零宽负向先行断言,要求接下来的字符不与p匹配。
. : 表示模糊匹配,一个点可以匹配任意一个字符。
| : 表示或
\ : 表示转义字符
6、标志位(修饰符)
i | 执行不区分大小写的匹配 |
g | 执行一个全局匹配 |
m | 多行匹配模式,^匹配一行的开头和字符串的开头,$匹配一行的结束和字符串的结束 |
7、非贪婪的重复
上面讲的匹配重复字符是尽可能多地匹配,而且允许后续的正则表达式继续匹配,我们称之为“贪婪的”匹配。我们同样可以使用正则表达式进行非贪婪匹配,只须在待匹配的字符后跟随一个问号即可:“??”、“+?”、“*?”或“{1,5}?”。
比如,转让那个则表达式/a+/可以匹配一个或多个连续的字母a。当使用“aaa”作为匹配字符串时,正则表达式会匹配它的三个字符,但是/a+?/也可以匹配一个或多个连续的字母a,但它是尽可能少的匹配,我们同样将“aaa”作为匹配字符串,后一个模式只能匹配第一个a。
8、分组
带圆括号的表达式的另一个用途是允许在同一正则表达式的后部引用前面的子表达式,这是通过在字符“\”后面加一位或多为数字来实现的,这个数字指定了带圆括号的子表达式在正则表达式中的位置。例如:/['"][^'"]*['"]/可以写成/['"][^'"]*\1/,不能在字符类中使用这种引用,这样的写法是非法的:/['"][^\1]*\1/。
二、RegExp的属性
每个RegExp都有5个属性。
属性source是一个只读的字符串,包含正则表达式的文本。
属性global是一个只读的布尔值,用以说明这个正则表达式是否带有修饰符g。
属性ignoreCase是一个只读的布尔值,用以说明这个正则表达式是否带有修饰符i。
属性multiline是一个只读的布尔值,用以说明这个正则表达式是否带有修饰符m。
属性lastIndex是一个可读/写的整数,如果匹配模式带有g修饰符,这个属性存储在整个字符串中下一次检索的开始位置,这个属性会被exec()和test()方法用到。
三、正则表达式对象的方法
1、正则对象.test(字符串) //返回值是布尔值 如果匹配正则,返回true,否则,返回false
调用test()和调用exec()等价,这样一来,就可以用test()来遍历字符串,就想用exec()一样。
2、正则对象.exec(字符串) //返回值是数组,如果没有匹配内容,返回null
它返回一个数组,就像match()方法为非全局检索返回的数组一样,这个数组的第一个元素包含的是与正则表达式相匹配的字符串,余下的元素是与圆括号内的子表达式相匹配的字符串。属性index包含了发生匹配的字符位置,属性input引用的是正在检索的字符串
当正则表达式带有修饰符g时,它将把当前正则表达式的对象的lastIndex属性设置为紧挨着匹配子串的位置。当同一个正则表达式第二次调用exec()时,它将从lastIndex属性所指示的字符处开始搜索。如果exec()没有发现任何匹配结果,它会将lastIndex()重置为0。
var pattern = /Java/g;
var text = "JavaScript is more fun than Java";
var result;
while((result = pattern.exec(text)) != null) {
console.log("Matched '" + result[0] + "'" + "at position " + result.index + ";next search begins at " + pattern.lastIndex);
}
四、字符串方法
1、字符串对象.replace(正则,新串)
如果在替换字符串中出现了$加数字,那么replace()将用与指定的子表达式相匹配的文本来替换这两个字符。例如:可以用它将一个字符串中的英文引号来替换为中文半角引号
//一段引用起始于引号,结束于引号
//中间的内容区域不能包含引号
var quote = /"([^"]*)"/g;
//用中文半角引号替换英文引号,同时要保持引号之间的内容(存储在$1中)没有被修改
text.replace(quote,'“$1”');
2、字符串对象.match(正则对象) 返回值是数组,如果没有匹配内容,返回null
如果该正则表达式设置了修饰符g,则该方法返回的数组包含字符串中的的所有匹配结果。
"1 plus 2 equals 3".match(/\d+/g); //返回["1","2","3"]
如果这个正则表达式没有设置修饰符g,match()就不会进行全局检索,它只检索第一个匹配。但即使match()执行的不是全局检索,它也返回一个数组。在这种情况下,数组的第一个元素就是匹配的字符串,余下的元素则是正则表达式中用圆括号括起来的子表达式。
split()方法的参数也可以是一个正则表达式。
3、字符串对象.search(正则对象) 返回查找到的字符下标位置,如果没有找到,返回-1 类似indexOf()
如果search()的参数不是正则表达式,则首先会通过RegExp构造函数将它转换为正则表达式,不支持全局检索,因为它会忽略正则表达式参数中的修饰符g。
文章参考来源:《JavaScript 权威指南》(原书第六版) 作者 弗兰纳根