JS正则表达式

来源:互联网 发布:淘宝可以寄到台湾吗 编辑:程序博客网 时间:2024/06/07 23:49

 最基本的写法:var reCat = new RegExp("cat");

带参数的学法:var reCat = new RegExp("cat","g");其中参数g表示匹配字符串中出现的所有"cat".如果不区分大小写,可以加入"i"参数.如var reCat = new RegExp("cat","gi") 匹配所有,并且不区分大小写.

g是global的缩写,i是case-insensitive的缩写

Perl风格的正则表达式字面量写法:var reCat = /cat/gi 一对"/"表示开始结束.

 

//--------------------------------------正则表达式中的方法使用------------------------------------------

test()方法的使用:

var sToMatch = "cat"; //用以匹配的源字符串串

var reCat = /cat/; //正则表达式对象

var reCat.test(sToMatch); //调用RegExp的test方法来匹配.出现一次也返回true;

 

exec()方法的使用:

var sToMatch = "a bat, a Cat, a fAt baT, a faT cat"; //用以匹配的源字符串串

var reAt = /at/; //正则表达式对象

var var arrMatches = reAt.exec(sToMatch); //调用RegExp的exec方法来匹配.

exec()方法返回一个数组,数组中的第一个条目是第一个匹配,其他的是反向引用.

这里,arrMatches只包含一个条目:第一个"at"的实例(在单词"bat"中的那个).

 

match()方法的使用:

var sToMatch = "a bat, a Cat, a fAt baT, a faT cat"; //用以匹配的源字符串串

var reAt = /at/gi;

var arrMatches = sToMatch.match(reAt);

match()返回包含在字符串中的所有的匹配的数组.

arrMatches[0] = "at"; //"bat"

arrMatches[1] = "at"; //"Cat"

arrMatches[2] = "At"; //"fAt"

arrMatches[3] = "aT"; //"baT"

arrMatches[4] = "aT"; //"faT"

arrMatches[4] = "at"; //"cat"

 

search()方法的使用:

var sToMatch = "a bat, a Cat, a fAt baT, a faT cat"; //用以匹配的源字符串串

var reAt = /at/gi;

alert(sToMatch.search(reAt)); //outputs "3";

这个方法和indexOf()有些类似,但是这个使用的是一个RegExp对象而非仅仅一个字符串.返回字符串中出现的第一个匹配的位置

 

//------------------------------------------字符串中方法带正则表达式的使用-----------------------------

 

replace()方法的使用

1.

var sToChange = "The sky is red. ";

var reRed = /red/;

//alert(sToChange.replace("red","blue")); //这是以前的普通写法

alert(sToChange.replace(reRed,"blue")); //outputs "The sky is blue"

这里第一个参数用正则表达式代替,"blue"替换了正则表达式匹配的单词.所以输出"The sky is blue".

 

2.

var sToChange = "The sky is red. ";

var reRed = /red/;

var sResultText = sToChange.replace(reRed,function(sMatch) {

return "blue";

 }); 

alert(sResultText);

这里演示了第二个参数为匿名方法的使用.第一个参数同样是一个RegExp类.

注意:这里的替换只替换第一出现的"red"也就是说如果源字符串是:"The sky is red. I like red." 那么替换后的结果是"The sky is blue. I like red."如果想替换所有的red,那么RegExp表达式应该添加参数,如:/red/g

 

split()方法的使用:

var sColor = "red,blue,yellow,green";

//var arrColors = sColor.split(","); //以前的普通写法

var reComma = //,/;

var arrColors = sColor.split(reComma);

虽然结果和普通写法一样,但是这里传入的是一个RegExp类型.注意","在正则表达式中有自己的含义,所以这里用"/"转译.

 

//----------------------------------------正则表达式中的几个元字符--------------------------------------------

 

元字符作为字面量时都需要转义,js中的元字符包括下面十二个

( [ { / ^ $ | ) ? * + .

几个简单实例:

匹配一个问号: var reQMark = //?/; 或者 var reQMark = new RegExp("//?");

第二实例为什么要用两个"/",因为"/"在字符串中也是属于转义字符.即"//"转换后是"/".(我叙述不清有点乱,自行理解.)

 

也可以用ASCII来表示字符:(提一下)

var sColor = "blue";

var reB = //x62/;

alert(reB.test(sColor)); //匹配b,outputs "true";

 

另外还有些预定义的字符,大致和平时使用的一样含义:

/t制表符   /n换行   /r回车   /f换页   /a(alert字符)   /e(escape)字符   /cX(与X相对应的控制字符)   /b回退字符   /v垂直制表符   /0 空字符

实例(删除字符中所有的换行符):

var sNewString = sStringWithNewLines.replace(//n/g,"");

 

 

//----------------------------------------字符类-------------------------------------------------------

字符类分为好几种:简单类,负向类,范围类,组合类和预定义类.

 

1.简单类

var sToMatch = "a bat, a Cat, a fAt baT, a faT cat"; //用以匹配的源字符串串

var reBatCatRat = /[bcf]at/gi;

var arrMatches = sToMatch.match(reBatCatRat);

输出结果:

alert(arrMatches.length); //outputs "5";

arrMatches[0] == "bat"; //true

arrMatches[1] == "Cat"; //true

arrMatches[2] == "fAt"; //true

arrMatches[3] == "faT"; //true

arrMatches[4] == "cat"; //true

 

2.负向类

var sToMatch = "a bat, a Cat, a fAt baT, a faT cat"; //用以匹配的源字符串串

var reBatCatRat = /[^bc]at/gi;

var arrMatches = sToMatch.match(reBatCatRat);

输入结果:

alert(arrMatches.length); //outputs "2";

arrMatches[0] == "fAt"; //true

arrMatches[1] == "faT"; //true

 

3.范围类

var sToMatch = "num1,num2,num3,num4,num5,num6,num7,num8,num9";

var reOneToFour = /num[1-4]/gi;

var arrMatches = sToMatch.match(reOneToFour);

 

4.组合类(combination class)

var reCombination = /[a-mA-M1-4/n]/; //匹配一个a到m或者A-M或者1-4或者一个换行符的字符

 

5.预定义类

 

____________________________________________________

 

. [^/n/r] 除了换行和回车之外的任意字符

/d [0-9] 数字

/D [^0-9] 非数字字符

/s [/t/n/x0B/f/r] 空白字符

/S [^/t/n/x0B/f/r] 非空白字符

/w [a-zA-Z_0-9] 所有的字母,所有的数字和下划线(单词字符)

/W [^a-zA-Z_0-9] 非单词字符

 

 

//----------------------------------------量词------------------------------------------------------

 

1.简单量词

? 出现0次或1次

* 任意次

+ 至少一次

{n} 一定出现n次

{n,m} 至少n次,最多m次

{n,} 至少出现n次

 

2.贪婪的,惰性的和支配性的量词

贪婪的:先看整个的字符串是否匹配,如果没有发现匹配,去掉该字符中的最后一个字符,并且再次尝试.一直如此重复,直到发现一个匹配或者字符串中不剩任何字符.

惰性的:先看第一个字符是否匹配,如果单独这一个字符还不够,就读入下一个字符,组成两个字符的字符串,如果还是不够,重复前一步工作,直到发现匹配或者整个字符串都经检查过无匹配.

支配性的:只尝试匹配整个个字符串,如果整个字符串不能产生匹配,不做进一步尝试.

默认的简单量词就是贪婪的,如果想使用惰性的则多加一个"?"号,而支配性的则是"+"号.

贪婪 惰性 支配

? ?? ?+

* *? *+

+ +? ++

{n} {n}? {n}+

{n,m} {n,m}? {n,m}+

{n,} {n,}? {n,}+

 

问题(想获得匹配是:"abbb","aabbb","aaabbb",应该是那种匹配):

var sToMatch = "abbbaabbbaaabbb1234";

var re1 = /.*bbb/g;  //贪婪匹配

var re2 = /.*?bbb/g; //惰性匹配

var re3 = /.*+bbb/g; //支配匹配

答案自行思考.

 

 

//-----------------------------------------正则表达式中的分组-------------------------------------------------

var regDogDog = /(dog){2}/g; 相当于 var regDogDog = /dogdog/g;

前者利用了分组,把dog看作一组,后面跟了一个量词,表示出现的次数.这就是个简单的分组.

当然可以分组套分组

var re = /(mom( and dad)?)/; //match "mom" or "mom and dad"

匹配一个头尾空白的: var reExtraSpace = /^/s*(.*?)/s+$/;

这样可以自定义自己的trim函数了.

String.prototype.trim = function() {

var reExtraSpace = /^/s*(.*?)/s+$/;

return this.replace(reExtraSpace,"$1");

};

var sTest = "         this is a test         ";

alert("[" + sTest + "]"); //outputs "[         this is a test         ]"

alert("[" + sTest.trim() + "]"); //outputs "[this is a test]";

 

分组中的反向引用:

如表达式(A?(B?(C?)))将产生三个反向引用

a.(A?(B?(C?)))

b.(B?(C?))

c.(C?)

反向引用可以使用test(),match(),search()方法后,从RegExp构造函数中获得:

var sToMatch = "#123456789";

var reNumbers = /#(/d+)/;

reNumbers.test(sToMatch);

alert(RegExp.$1) //outputs "123456789"

 

var sToMatch = "dogdog";

var reDogDog = /(dog)/1/;

alert(reDogDog.test(sToMatch)); //outputs "true"

reDogDog首先创建一个dog的组,然后又被特殊转义序列/1引用,使得这个正则表达式等同于/dogdog/.

 

var sToChange = "1234 5678";

var reMatch = /(/d{4}) (/d{4})/;

var sNew = sToChange.replace(reMatch,"$2 $1");

alert(sNew); //outputs "5678 1234"

 

 

非捕获性分组:在分组的左括号后面添加"?:"符号即可.

var sToMatch = "#123456789";

var reNumbers = /#(?:/d+)/;

reNumbers.test(sToMatch);

alert(RegExp.$1); //outputs ""

在较长的正则表达式中存储反向引用会降低匹配速度,非捕获性分组可以提高性能,因为它不会存储反向引用

String.prototype.stripHTML = funciton() {

var regTag = /<(?:.|/s)*?>/g; //非捕获分组,匹配"<"和任意数量的"."或者空白,并且是惰性模式.最后是">"

return this.replace(reTag,"");

};

 

var sTest = "<b>This would be bold </b>";

alert(sTest.stripHTML()); //outputs "This would be bold"

 

-----------------------------------候选(OR)模式------------------------------------------------------------

//分组OR模式并获取

var sToMatch1 = "red";

var sToMatch2 = "black";

var sToMatch3 = "green";

var reRedOrBlack = /(red|black|green)/;

alert(reRedOrBlack.test(stoMatch1) + " : " + reRedOrBlack.$1); //outputs "true : red"

alert(reRedOrBlack.test(stoMatch2) + " : " + reRedOrBlack.$1); //outputs "true : black"

alert(reRedOrBlack.test(stoMatch3) + " : " + reRedOrBlack.$1); //outputs "true : green"

 

//替换脏话

var reBadWords = /badword|anotherbadword/gi;

var sUserInput = "This is a string using badword1 and badword2.";

var sFinalText = sUserInput.replace(reBadWords,"****");

alert(sFinalText); //outputs "This is a string using **** and ****"

 

-----------------------------------前瞻..后顾------------------------------------------------

 

(?<= ... ) 后顾等

(?<! ... ) 后顾不等

(?= ...) 前瞻等

(?! ...) 前瞻不等

 

 

前瞻(lookahead)告诉正则表达式向前看一些字符,而不移动其位置.

前瞻分为正向前瞻后负向前瞻.

正向前瞻表示后面跟的内容匹配前瞻内容(方向都是 --->),而负向则后面跟的内容不匹配其前瞻内容.

创建正向前瞻将模式放在(?=和)之间,注意:这不是分组.

var sToMatch1 = "bedroom";

var sToMatch2 = "bedding";

var reBed = /(bed(?=room))/; //注意(?=room)不是分组,而是正向前瞻

alert(reBed.test(sToMatch1)); //outputs "true"

alert(regExp.$1); //outputs "bd"

alert(reBed.test(sToMatch2)); //outputs "false"

 

负向前瞻的创建放在(?!和)之间

var sToMatch1 = "bedroom";

var sToMatch2 = "bedding";

var reBed = /(bed(?!room))/; //负向前瞻(?!room),不是分组! //负向前沿只匹配后面不跟着"room"的bed

alert(reBed.test(sToMatch1)); //outputs "false"

alert(reBed.test(sToMatch2)); //outputs "true"

alert(RegExp.$1); //outputs "bed"

 

至于后顾,和前瞻类似.

 

-----------------------------------------------------边界------------------------------------------

^ 行开头

$ 行结尾

/b 单词边界

/B 非单词边界

 

查找一个单词,但他只出现在行尾

var sToMatch = "Important word is the last one.";

var reLastWord = /(/w+)/.$/;

reLastWord.test(sToMatch);

alert(RegExp.$1); //outputs "one"

 

查找一个单词,但值出现在行首

var sToMatch = "Important word is the last one.";

var reFirstWord = /^(/.+?)/b/;  //这里用惰性,如果是贪婪,则匹配整个字符转了

//var reFirstWord = /^(/w+)/;  //这个也可行

reFirstWord.test(sToMatch);

alert(RegExp.$1); //outputs "Important"

 

抽取单词

var sToMatch = "First second third fourth fifth sixth";

var reWords = //b(/S+?)/b/g;

//var reWords = /(/w+)/g; //这个也行

var arrWords = sToMatch.match(reWords);

 

------------------------------------多行模式------------------------------------

var sToMatch = "First second/nthird fourth/nfifth sixth";

var reLastWordOnLine = /(/w+)$/g;

var arrWords = reLastWordOnLine.match(sToMatch);

这里获取的最后一个单词是sixth,但实际上有3行,想获取的单词是sencond,fourth和sixth.所以需要在第二句话添加一个参数m.

var reLastWordOnLine = /(/w+)$/gm;

这样,添加m后会把换行符解析为一个$,并且也是一个^的开始.

所以匹配 var reFirstWordOnline = /^(/w+)/;也会获得期望的三个单词而不是一个.

 

----------------------------------RegExp对象--------------------------------

global -- Boolean,表示g(全局选项)

ignoreCase -- Boolean,表示i是否忽略大小写

lastIndex -- int 表示下次匹配将会从哪个字符位置开始(只有使用exec()或test()函数才会填入,否则为0)

multiline -- Boolean,表示m(多行模式选项)

source -- 表达式的字面量形式.如:/[ba]*/的source返回"[ba]*"

 

var sToMatch = "bbq is short for barbecue";

var reB = /b/g;

reB.exec(sToMatch);

alert(reB.lastIndex); //outputs "1"

reB.exec(sToMatch);

alert(reB.lastIndex); //outputs "2"

reB.exec(sToMatch);

alert(reB.lastIndex); //outputs "18"

//reB.lastIndex = 0;

//alert(reB.lastIndex); //如果改变索引后:outputs "1"

reB.exec(sToMatch);

alert(reB.lastIndex); //outputs "21"

 

静态属性

完整名 短名字 功能

input $_ 最后用于匹配的字符串(传递给exec()或test()的字符串)

lastMatch $& 最后匹配的字符

lastParent $+ 最后匹配的分组

leftContext $` 在上次匹配的前面的字串

multiline $* 用于指定是否所有的表达式都使用多行模式的布尔值

rightContext $' 在上次匹配之后的字串

 

var sToMatch = "this has been a short, short summer";

var reShort = /(s)hort/g;

reShort.test(sToMatch);

alert(RegExp.input); //outputs "this has been a short, short summer"

alert(RegExp.leftContext); //outputs "this has been a "

alert(RegExp.rightContext); //outputs ", short summer"

alert(RegExp.lashMatch); //outputs "short"

alert(RegExp.lastParen); //outputs "s"

0 0
原创粉丝点击