欢迎技术交流。 QQ:138986722
继续正则表达式——量词:
/**
* 量词可以指定某个特定模式出现的次数。当指定某个模式应当出现
* 的次数时、可以指定硬性数量(例如、某个字符应该出现三次)、也
* 可以指定软性数量(例如、这个字符至少应该出现一次、不过可以
* 重复任意次)。
代码 描述
? 出现零次或一次
* 出现零次或多次(任意次)
+ 出现一次或多次(至少出现一次)
{n} 一定出现n次
{n,m} 至少出现n次但不超过m次
{n,} 至少出现n次
例如:想匹配bread,read,red这几个单词
*/
var sIf = /b?rea?d/;
sIf = /b{0,1}rea{0,1}d/; //另外一种方法
/**
*
* 例如匹配 bd,bad,baad,baaad
*
* 正则表达式 匹配
ba?d "bd","bad"
ba*d "bd","bad","baad","baaad"
ba+d "bad","baad","baaad"
ba{0,1}d "bd","bad"
ba{0,}d "bd","bad","baad","baaad"
ba{1,}d "bad","baad","baaad"
*/
/**
* 匹配:bead、baed、beed、baad、bad
*/
//var eaTest = /b[ea]{1,2}d/ ;
var sToMatch = "abbbaabbbaaabbb1234";
var re1 = /.*bbb/g; //贪婪
var re2 = /.*?bbb/g; //惰性
var re3=/.*+bbb/g; //支配
alert("re1:"+re1.exec(sToMatch)+" \n--re2:"+re2.exec(sToMatch));
贪婪的、惰性的和支配性的量词
贪婪量词先看整个字符串是否匹配、如果没有发现匹配、它就去掉
该字符串中的最后一个字符、并再次尝试。如果还是没有发现匹配
、那么再次去掉最后一个字符、这个过程会一直重复直到发现一个
匹配或者字符串不剩任何字符。
惰性量词首先看字符串中的第一个字符是否匹配、如果单独这一个
字符还不够、就读入下一个字符、组成两个字符的字符串。如果还
是没有发现匹配、惰性量词继续从字符串中添加字符知道发现匹配
或者整个字符串都检查过也没有匹配。惰性量词和贪婪量词的工作
方式恰好相反。
支配量词只尝试匹配整个字符串。如果整个字符串不能产生匹配、
不做进一步尝试。支配词其实简单的说、就是一刀切。
怎样表示贪婪、惰性和支配量词呢?正是完全使用星号、加号和问号。
例如、单独一个问号(?)是贪婪的、但是问号后面在跟一个问号(??)就
是惰性的。要使问号成为支配量词、在后面加上一个加号(?+)。
贪婪 惰性 支配 描述
? ?? ?+ 零次或一次出现
* *? *+ 零次或多次出现
+ +? ++ 一次或多次出现
{n} {n}? {n}+ 恰好n次出现
{n,m} {n,m}? {n,m}+ 至少n次至多m次出现
{n,} {n,}? {n,}+ 至少n次出现
---------------原文出自《javaScript高级程序设计》-----------------------
复杂模式——分组:
/**trim() 方法:
* 分组、
* 假设想匹配字符串"dogdog"。使用目前获得的知识
* 可能估计表达式应该类似:
*/
var res = /dogdog/g;
alert(res.test("dogdog"));
//分组重写:
var res = /(dog){2}/g;
alert(res.test("dogdog"));
//分组量词使用
var re1 = /(dog)?/; //出现零次或一次
var re2 = /(dog)*/; //出现零次或多次(任意次)
var re3 = /(dog)+/; //出现一次或多次(至少出现一次)
//同时也可以将分组放在中间
var res = /(mmm( and nnn)?)/;
/**反向引用:
* trim() 方法
* "\s" 匹配所有空格 .
* "." 小数点可以匹配除了换行符(\n)以外的任意一个字符.
* "^" 与字符串开始的地方匹配,不匹配任何字符.
* "{1}quot; 与字符串结束的地方匹配,不匹配任何字符.
* var reExt = /^\s*(.*?)\s+$/ ;
* 这个正则表达式将查找字符串开头的零个或多个空白、
* 跟着是任意数目的字符(在分组中捕获的字符)、
* 最后字符串结尾处又是零个或多个空白。
* 通过配合使用String对象的replace()方法以及反向引用、
* 就可以自定义自己的trim()方法:
*/
String.prototype.trim = function(){
var reExt = /^\s*(.*?)\s+$/ ;
/*
* $1表示的就是左边表达式中括号内的字符,即第一个子匹配,
* 同理可得$2表示第二个子匹配。什么是子匹配呢?通俗点讲,
* 就是左边每一个括号是第一个字匹配,第二个括号是第二个子匹配。
*/
return this.replace(reExt,"$1");
};
alert("'"+" fdsa ".trim()+"'");
/**候选:
* 反向引用
* 每个分组都被存放在一个特殊的地方以备将来使用。
* 这些存储在分组中的特殊值、我们称之为反向引用。
* 首先、使用正则表达式对象的test()、match()、或search()方法后、
* 反向引用的值可以从RegExp构造函数中获得
*/
var reg = /#(\d+)/;
alert(reg.test("#123456789"));
/*
* 输出的是(\d+)匹配的内容:123456789
* 如果有第二个分组()则$2依此类推
*/
alert("'"+RegExp.$1+"'");
/**
* 反向引用示例:
*/
var reg = /(\d{3})(\d{3})/;
/*
* $1等同于:456
* $2等同于:123
*/
alert("456123".replace(reg,"$2$1"));
/**非捕获性分组:
* 候选
* 一个表达式、即匹配"古道西风"又匹配"旦旦而学"
* "|"管道符:左右两边表达式之间 "或" 关系
*/
var reg = /(古道西风|旦旦而学)/;
alert(reg.test("旦旦而s"));
/**去掉文本中所有HTML标签:
* 非捕获性分组
* 在较长的正则表达式中、存储反向引用会降低匹配速度。
* 通过使用非捕获性分组、仍然可以拥有与匹配字符串列同样的能力、
* 而无需要存储结果的开销。
* 创建一个非捕获性分组、只要在左括号的后面加上一个问号和一个紧跟的冒号:
*/
var reg = /#(?:\d+)/;
reg.test("#456123");
alert(RegExp.$1);
String.prototype.stripHTML = function (){前瞻:
var reTag = /<(?:.|\s)*?>/g;
return this.replace(reTag,"");
};
/*
* 如果非要在双引号字符串使用双引号则加上\转义
*/
alert("<option value=\"1\">1</option>".stripHTML());
/**边界:
* 前瞻
* 它告诉正则表达式运算器向前看一些字符而不移动其位置。
* 同样存在正向前瞻和负向前瞻。
* 正向前瞻检查的是接下来出现的是不是某个特定字符集。
* 而负向前瞻则是检查接下来的不应该出现的特定字符集。
* 创建正向前瞻要将模式放在(?=和)之间。
*/
var testStr = "begRooms";
var testAry = "begTest";
var reg = /beg(?=Room)/; //匹配后面跟着Room的beg
alert(reg.test(testStr));//true
alert(reg.test(testAry));//false
/*
* 负向前瞻
* 要创建它要将模式放在(?!和)之间。
*/
var reg = /beg(?!Room)/; //匹配后面不跟着Room的beg
alert(reg.test(testStr)); //false
alert(reg.test(testAry)); //true
/**
* 边界
* \w: 匹配包括下划线的任何单词字符,等价于 [A-Z a-z 0-9_]
* \W: 匹配任何非单词字符,等价于 [^A-Z a-z 0-9_]
* \b:单词边界
* \B:非单词边界
*/
var sT = "my English is very shit.";
var reg = /(\w+)\.$/;
alert(reg.test(sT)); //true
alert(RegExp.$1); //shit
var reg = /^(\w+)/;
alert(reg.test(sT)); //true
alert(RegExp.$1); //my
var reg = /^(.+?)\b/;
reg.test(sT);
alert(RegExp.$1); //my