`

关于正则表达式的一些笔记

阅读更多

      幸好电脑有搜索功能,关键字一查询很是方便。这里是我以前看javascript高级编程一书中记录下来的关于正则表达式的一些东西,好多也可以运用的别的正则当中.

最基本的写法: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"

 

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics