Chapter 7 正则表达式
1:定义RegExp对象:
1: var reCat = new RegExp(“cat”,”gi”);
2: var reCar = /Cat/gi
g是global的缩写,
i是insensitive的缩写(表示大小写不敏感)
2: 使用RegExp对象:
RegExp对象的方法:test() 和 exec()
String 对象的方法:match(), search(), replace(), split()
――――――――――――――――――――――――――――――――――――
test 方法:
var sToMatch = "cat";
var reCat = /cat/;
alert(reCat.test(sToMatch)); //output true;
――――――――――――――――――――――――――――――――――――
exec方法:
返回一个字符串数组,
第一个条目是第一个匹配, 其它的都是反向引用
var sToMatch = "http://msdn.microsoft.com:80/scripting/default.htm";
var reS = /(\w+):\/\/([^:]+)(:\d*)?([^# ]*)/;
var arrMatches=reS.exec(sToMatch);
alert(arrMatches.length);
for(i=1;i<arrMatches.length;i++)
alert(arrMatches[i]);
exec()方法返回一个数组, 数组中的第一个题目是第一个匹配,
其它的都是反向引用, 在上面的例子中:
a[0]是匹配到的字符串,即:http://msdn.microsoft.com:80/scripting/default.htm
a[1]
包含
"http"
a[2]
包含
"msdn.microsoft.com"
a[3] 包含 ":80"
a[4] 包含 "/scripting/default.htm"
(也可以用RegExp.$1、RegExp.$2、RegExp.$3、RegExp.$4取值)
――――――――――――――――――――――――――――――――――――
match方法
返回一个包含在字符串中所有匹配的数组
var sToMatch = "a bat, a cat, afat baT, a
faT cat";
var reAt = /at/gi;
var arrMatches = sToMatch.match(reAt);
for(i = 1; i < arrMatches.length; i++)
alert(arrMatches[i]);
――――――――――――――――――――――――――――――――――――
search方法
返回在字符串中出现的第一个匹配的位置
var sToMatch = "a bat, a cat, afat baT, a
faT cat";
var reAt = /at/gi;
alert(sToMatch.serach(reAt)); //output 3
――――――――――――――――――――――――――――――――――――
replace方法
用第二个参数来替换第一个参数,返回替换后的字符串
var sToChange = "The sky is red, the sky is red";
var reRed = /red/;
alert(sToChange.replace(reRed,"blue"));
Result: The sky is blue, the sky is red.
如果要替换“red”的所有出现, 必须指明/red/g
var reRed = /red/g;
alert(sToChange.replace(reRed,"blue"));
Result: The sky is blue, the sky
is blue.
Replace最强大的用法是接受一个函数作为第二个参数。这个函数可以接受一个参数(即 匹配正则表达式的文本),并返回替换文本。
――――――――――――――――――――――――――――――――――――
split方法
将字符串分割成一系列子串,并通过数组返回。
var sColor = "red,blue,black,white,yellow,green";
var reComma = /\,/;
var arrColors = sColor.split(reComma);
for(i=1;i<arrColors.length;i++)
alert(arrColors[i]);
3: 正则表达式的组成部分
l
元字符
l
字符类
l
量词
3.1 元字符:
( [
{ \ ^ $ | ) ? * + . , 使用上述的元字符时,需要转义
例如:
var reQMark = /\?/;
var reQMark = new RegExp("\\?");两个反斜杠是因为: ”\”在字符串中本身需要转义
3.2 字符类
简单类:[abc] 匹配a或b或c
负向类:[^abc] 匹配除了a,b和c的所有字符
范围类:[a-z] 匹配a到z
组合类:由上述几种字符类组合而成, 内部的类之间不能有空格 [a-zA-Z0-9]
预定义类:
代码
|
等同于
|
匹配
|
.
|
[^\n\r]
|
除了换行和回车之外的任意
|
\d
|
[0-9]
|
数字
|
\D
|
[^0-9]
|
非数字
|
\s
|
[
\t\n\x0B\f\r]
|
空白字符
|
\S
|
[^
\t\n\x0B\f\r]
|
非空白字符
|
\w
|
[a-zA-Z0-9_]
|
单词字符(字母数字下划线)
|
\W
|
[^a-zA-Z0-9_]
|
非单词字符
|
3.3 量词
3.3.1简单量词:
代码
|
描述
|
?
|
出现0次或1次
|
*
|
出现0次或多次
|
+
|
出现1次或多次
|
{n}
|
一定出现n次
|
{n,}
|
至少出现n次
|
{n,m}
|
出现n次到m次
|
正则表达式
|
描述
|
ba?d
|
bd, bad
|
ba+d
|
bad, baad, baaad,…
|
ba*d
|
bd, bad, baad,
baaad,…
|
ba{1}d
|
bad
|
ba{1,}d
|
bad, baad, baaad,…
|
ba{1,2}d
|
bad, baad
|
3.3.2 贪婪的,惰性的和支配性的量词
贪婪量词:
先看整个字符串是否匹配;如果没有,去掉最后一个字符;重复这个过程,一直到发现 匹配或者字符串不剩余任何字符。
惰性量词:
先看字符串中的第一个字符是否匹配,
如果不, 则读入下一个字符,重复一直到发现 匹配或者整个字符串都已经检查过了。
支配性量词:
只尝试匹配整个字符串。(IE不支持, Mozilla视为贪婪量词处理)
贪婪
|
惰性
|
支配
|
?
|
??
|
?+
|
*
|
*?
|
*+
|
+
|
+?
|
++
|
{n}
|
{n}?
|
{n}+
|
{n,m}
|
{n,m}?
|
{n,m}+
|
{n,}
|
{n,}?
|
{n,}+
|
var sToMatch = "abbbaabbbaaabbb1234";
var re1 = /.*bbb/g;
var re2 = /.*?bbb/g;
//var re3 = /.*+bbb/g;
var arrRes1 = sToMatch.match(re1);
var arrRes2 = sToMatch.match(re2);
//var arrRes3 = sToMatch.match(re3);
alert(arrRes1); //output "abbbaabbbaaabbb"
alert(arrRes2); //output "abbb","aabbb","aaabbb"
4: 分组
分组即用一系列的括号包围一系列字符,
字符类以及量词
示例: 轻松实现String的trim方法:
String.prototype.trim = function(){
var reExtraSpace = /^\s*(.*?)\s+$/;
return this.replace(reExtraSpace,"$1");
}
var sTest = "
hello, guy ";
alert(sTest.trim());
5: 反向引用
如果正则表达式中含有分组, 分组中的值将被保存。反向引用就是存储在分组中的特殊值
例如表达式(a?(b?(c?)))将产生编号从1-3的三个反向引用:
(1): (A?(B?(C?)))
(2):
(B?(C?))
(3):
(C?)
获取反向引用:RegExp.$1, RegExp.$2
在正则表达式中包含反向引用: /(dog)\1/ 同 /dogdog/
反向引用在replace方法中:$1 $2
6: 候选
var
reRedOrBlack = /(red|black)/
7: 非捕获性分组
不创建反向引用:(?:pattern)
var
renumbers = /#(?:\d+)/;
8: 前瞻
正向前瞻检查的是接下来出现的是不是某个特定的字符
负向前瞻检查的是接下来的不应该出现的字符
JavaScript不支持负向前瞻
示例:
var sToMatch1 = "bedroom";
var reBed = /bed(?=room)/;
alert(reBed.test(sToMatch1)); //output true
9: 边界
边界
|
描述
|
^
|
行开头
|
$
|
行结尾
|
\b
|
单词的边界
|
\B
|
非单词的边界
|
10: 多行模式
var reMultiLine = /pattern/m;
var sToMatch = "First second" +
" third forth" +
" fifth sixth";
var reLastWord1 = /(\w+)$/g;
var reLastWord2 = /(\w+)&/gm;
var reBeginWord1 = /^(\w+)/g;
var reBeginWord2 = /^(\w+)/gm
alert(sToMatch.match(reLastWord1));
alert(sToMatch.match(reLastWord2));
alert(sToMatch.match(reBeginWord1));
alert(sToMatch.match(reBeginWord2));
日期的正则表达式:
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))$
加了时间验证的
^((((1[6-9]|[2-9]\d)\d{2})-(0?[13578]|1[02])-(0?[1-9]|[12]\d|3[01]))|(((1[6-9]|[2-9]\d)\d{2})-(0?[13456789]|1[012])-(0?[1-9]|[12]\d|30))|(((1[6-9]|[2-9]\d)\d{2})-0?2-(0?[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))-0?2-29-))
(20|21|22|23|[0-1]?\d):[0-5]?\d:[0-5]?\d$