7、正则表达式

7、正则表达式

7.1正则表达式支持
javascript对正则表达式的支持是通过ECMAScript的RegExp类实现的。RegExp对象的构造函
数可以有一个或两个参数。 第一个秒速了要进行匹配的模式字符串,第二参数制定了额外命
令。

var reCat = new RegExp("cat");
var reCat = new RegExp("cat","gi"); g为global缩写,要匹配字符串中所有cat。i不区分
大小写。
perl风格的语法
var reCat = /cat/gi;
创建regexp后,regexp 和 String对一些方法都可以使用。
var sToMatch = "cat";
var reCat = /cat/;
alert(reCat.test(sToMatch)); //outputs "true"
使用test()即使模式只在字符窜出现一次也返回true。如果每次出现都出现,使用exec()

exec()方法,有一个字符串参数,返回一个数组。数组中的第一个条目是第一个匹配;其他
是反向引用。
var sToMach = "a bat,a Cat,a fAt bat, a faT cat";
var reAt = /at/;
var arrMatches = reAt.exec(sToMatch);

arrMatches只包含一个条目: bat中的at;
如果要匹配所有 则使用String对象的match()方法

var sToMatch = "a bat,a Cat,a fAt bat, a faT cat";
var reAt = /.at/gi;
var arrMatches = sToMatch.match(reAt);

另一个叫做search()的字符串方法的行为与indexOf()有些类似,但是它使用一个RegExp对象
而非仅仅一个字符串。Search()方法返回在字符串中出现的一个匹配的位置。
var sToMatch = "a bat,a cat, a fat baT, a faT caT";
var reAt = /at/gi;
alert(sToMatch.search(reAt)); //outputs 3
注意全局匹配正则表达式 在使用search()时不起作用。

7.1.2 扩展的字符串方法
字符串的两个方法,也可以用正则表达式作参数。
一个是replace();可以用一个字符串(2)来替换第一个参数匹配的子串。

var sToChange = "The sky is red.";
alert(sToChange.replace("red","blue"));

这里,子字符串 "red" 被字符转blue替代,也可以用正则表达式:
var sToChange = "The sky is red.";
var reRed = /red/;
alert(sToChange.replace(reRed,"blue"));

replace 第二个参数可以指定一个函数,函数接受一个参数,即匹配的文本。

var sToChange = "The sky is red.";
var reRed = /red/;
var sResultText = sToChange.replace(reRed,function(sMatch){
return "blue";
});

alert(sResultText);

第二个方法为split(),它可以将字符串分割成一系列子串 数组返回。

var sColor = "red,blue,yellow,green";
var arrColor = sColor.split(",");

正则表达式:

var sColor = "red,blue,yellow,green";
var reComma = /\,/;
var arrColor = sColor.split(reComma);

7.2 简单模式

7.2.1元字符
(){}[]\^$?*+.
var reQMark = /\?/;
var reQMark = new RegExp("\\?"); 以这种形式表示的时候,所有的反斜杠都必须以两个反
斜杠表示。

7.2.2 使用特殊字符
可以通过直接使用字符来表示他们本身,也可以使用他们的ascii或者unicode指定字符。要
使用ascii来表示一个字符,则必须指定一个两位的16进制代码,并在前面加x. 用\x62.

var sColor = "blue";
var reB = /\x62/;
alert(reB.test(sColor)); //true

8位表示,142

var sColor = "blue";
var reB = /\142/;
alert(reB.test(sColor)); //true

如果要用Unicode表示字符,必须指定字符串的四位16进制表示。因此b的表示是\u0062:

var sColor = "blue";
var reB = /\u0062/;
alert(reB.test(sColor)); //true


换行符\n
删除字符串中的所有换行符。可以这样做
var sNewString = sStringWithNewLines.replace(/\n/g,"");

7.2.3字符类

字符类用于测试字符的组合。

1、简单类
架设想匹配"bat","cat","fat".
var sToMatch = "a bat, a Cat, a fAt baT, a fat Cat";
var reBatCatRat = /[bcf]at/gi;
var arrMatches = sToMatch.match(reBatCatRat);


也可以在简单类中包含特殊字符。
var sToMatch = "a bat, a Cat, a fAt baT, a fat Cat";
var reBatCatRat = /[\u0062cf]at/gi;
var arrMatches = sToMatch.match(reBatCatRat);

2、负向类
除了某些字符,匹配所有字符。这时候用负向类,^[^ab]

var sToMatch = "a bat,a cat, a fAt baT, a faT cat";
var reBatCatRat = /[^bc]at/gi;
var arrMatches = sToMatch.match(reBatCatRat);

fAt faT
3、范围类
[a-z]

var sToMatch = "num1,num2,num3,num4,num5,num6,num7,num8,num9";
var reOneToFour = /num[1-4]/gi;
var arrMatches = sToMatch.match(reOneToFour);
负向范围类
[^1-4]

4、组合类
由几种类组合而成的字符类。例如:
[a-m1-4\n] 内部类之间不要有空格。

正则表达式支持表示是中的 联合类和交叉类。这些正则不支持[a-m[p-z]],[a-m[^b-e]]

5、预定义类
var sToMatch = "567 9838 abc;
var reThreeNums = /[0-9][0-9][0-9]/;
alert(reThreeNums.test(sToMatch));


var sToMatch = "567 9838 abc;
var reThreeNums = /\d\d\d/;
alert(reThreeNums.test(sToMatch));

7.2.4 量词
1、简单量词
?*+{n}{n,m}{n,}

var reBreadReadOrRed = /b?rea?d/;

2、贪婪的、懒惰的和支配性的量词
所有量词默认都是贪婪的。
?懒惰匹配
支配量词 只匹配整个字符串。如果整个字符串不能产生匹配,不做进一步尝试。

7.3 复杂模式

可以由分组、反向引用、前瞻和其他一些强大的正则表达式组成。

7.3.1分组

var reDog = /(dog){2}/g;
var re1 = /(dog)?/;
通过混合字符,字符类,和量词,可以实现一些相当复杂的分组:
var re = /([bd]ad?)/;
var re = /mom( and dad)?/;
正则模拟一个trim();
var reExtraSpace = /^\s*(.*?)+$/;
通过配合使用String对象的replace()方法以及反向引用,
String.prototype.trim = function(){
var reExtraSpace = /^\s+(.*?)+$/;
return this.replace(reExtraSpace,"$1");
}

var sTest = " this is a test ";
alert("[" + sTest +"]");
alert("[" + sTest.trim() +"]");

7.3.2反向引用
var sToMatch = "#123456789";
var reNumbers = /#(\d+)/;
reNumbers.test(sToMatch);
alert(RegExp.$1);

然而还可以直接在定义分组的表达式中包含反向引用。
var sToMatch = "dogdog";
var reDogDog = /(dog)\1/;
alert(reDogDog.test(sToMatch));

用在replace中,通过使用$1,$2来实现,
var sToChange = "1234 56789";
var reMatch = /(\d{4}(\d{4}))/;
var sNew = sToChange.replace(reMatch,"$2$1");
alert(sNew);

7.3.3候选
用管道符,
var sToMatch1 = "red";
var sToMatch2 = "black";
var reTedOrBlack = /(red|black)/;
alert(reRedOrBlack.test(sToMatch1));
alert(reRedOrBlack.test(sToMatch2));

replace().
var reBadWords = /badword|anotherbadword/gi;
var sUserInput = "This is a string using badword1 and badword2.";
var sFinalText = sUserInput.replace(reBadWords,"****");
alert(sFinalText);

替换的* 和 badword字符相同。
var reBadWords = /badword|anotherbadword/gi;
var sUserInput = "This is a string using badword1 and badword2.";
var sFinalText = sUserInput.replace(reBadWords,function(sMatch){
return sMatch.replace(/./g,"*");
});
alert(sFinalText);

7.3.5前瞻
/(bed(?=room))/
ye jiao正向预查,如:
var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /(bed(?=room))/;
alert(reBed.test(sToMatch1)); //true
alert(RegExp.$1); //bed
alert(reBed.test(sToMath2)); //false

负向前瞻 反向预查
(?!beding)

var sToMatch1 = "bedroom";
var sToMatch2 = "bedding";
var reBed = /(bed(?!room))/;
alert(reBed.test(sToMatch1)); //false
alert(reBed.test(sToMath2));//true
alert(RegExp.$1); //bed

正则表达式不支持后瞻。支持这种模式:匹配b当且仅当它前面没有a。

7.3.6
^$\b(单词边界)\B(非单词边界)
7.3.7多行模式
g

7.4理解RegExp对象
7.4.1 实例属性
RegExp的实例有一些开发人员可以使用的属性:
global -- Boolean g
ignoreCase -- i
lastIndex -- 整数,代表下次匹配将会从哪个字符位置开始(只有当使用exec()或test()函
数才会填入,否则为0)
multiline -- m 多行
source -- 正则表达式的源字符串形式。 表达式/[ba]*/的source将返回"[ba]*".

var reTest = /[ba]*/i;
alert(reTest.global);
alert(reTest.ignoreCase);
alert(reTest.multiline);
alert(reTest.source);

真正有用的lastIndex,它可以告诉你正则表达式在某字符串中停止之前,查找了多远。
var sToMatch = "bbq is short for barbecue";
var reB = /b/g;
reB.exec(sToMatch);
alert(reB.lastIndex); //1
reB.exec(sToMatch);
alert(reB.lastIndex); //2
reB.exec(sToMatch);
alert(reB.lastIndex); //18
reB.exec(sToMatch);
alert(reB.lastIndex); //21

 

var sToMatch = "bbq is short for barbecue";
var reB = /b/g;
reB.exec(sToMatch);
alert(reB.lastIndex); //1
reB.lastIndex = 0;
reb.exec(sToMatch);
alert(reB.lastIndex); //1

7.4.2静态属性
静态的RegExp属性对所有的规则表达式都有效。都有两个名字,一个是复杂名和一个以美元
开头的短名。
input $_ 最后用于匹配的字符串(传递给exec()或test()的字符串)
lastMatch $& 最后匹配的字符
lastParen $+ 最后匹配的分组
leftContext $` 在上次匹配的前面子串
multiline $* 用于指定是否所有的表达式都使用多行模式的布尔值
rightContent $' 在上次匹配后的字符串

var sToMatch = "this has been a short,short summer";
var reShort = /(s)hort/g;
reS.test(sToMatch);
alert(RegExp.input); // this has been a short, short summer
alert(RegExp.leftContent); this has been a
alert(RegExp.rightContent); // ,short summer
alert(RegExp.lastMatch); //short
alert(RegExp.lastParen); //s

lastParen 属性包含最后匹配的分组。
var sToMatch = "this has been a short,short summer";
var reShort = /(s)hort/g;
reS.test(sToMatch);
alert(RegExp.$_); // this has been a short, short summer
alert(RegExp["$`"]); this has been a
alert(RegExp["$'"]); // ,short summer
alert(RegExp["$&"]); //short
alert(RegExp["$+"]); //s

对于multiline属性不同于其他属性,它不依赖最后一次匹配。
相反,它可以设置所有的正则表达式的m选项。

var sToMatch = "First second\nthird fourth\nfifth sixth";
var reLastWordOnLine = /(\w+)$/g;
RegExp.multiline = true;
var arrWords = sToMatch.match(reLastWordOnLine);
ie opera 并不支持 RegExp.multiline,所以最好单独对每个表达式设置m选项。

posted @ 2013-01-22 18:23  simpman  阅读(285)  评论(0编辑  收藏  举报