js之正则表达式

[b]一、RegExp [/b]
1.定义

var reCat = new RegExp("cat"); //匹配串中第一个"cat"
var reCat = new RegExp("cat","g"); //匹配串中所有的"cat","g"是global的意思
var reCat = new RegExp("cat","gi"); //匹配串中所有的"cat",不区分大消息,"i"是insensitive的缩写
var reCat = /cat/gi; //perl风格

2.方法
(1)test() 判断是否匹配,返回 true 或者 false

var sTomatch ="cat";
var reCat = /cat/;
alert(reCat.test(sTomatch));//outputs true

(2)exec() 返回一个数组,数组中的第一个条目是第一个匹配

var sTomatch = "a bat, a Cat, a fAt baT, a faT cat";
var reAt = /at/;
var arrMatches = reAt.exec(sTomatch);
alert(arrMatches.toString());

[b]二、String对象对正则表达式的支持 [/b]

(1)match()方法

var sTomatch = "a bat, a Cat, a fAt baT, a faT cat";
var reAt = /at/gi; var arrMatches = sTomatch.match(reAt);
alert(arrMatches.toString()); //outputs 'at,at, At ,aT ,aT ,at';

(2)replace()方法

var sToChange = "this red paper is not very red";
alert(sToChange.replace("red","blue"));//只替换第一个"red",outputs "this blue paper is not very red"
要想全部替换,如下

var sToChange = "this red paper is not very red";
var reRed = /red/gi;
alert(sToChange.replace(reRed,"blue"));


var str="ADF9DF9DF9",//那个文本文件中的字符串;
re=/9/gi,//匹配9
counter=0;//计数器
var rs = str.replace(re,function () {
counter++;//每出现一次匹配,函数就被执行一次,函数的返回值用来替换原值
return "#";
})

提取文件路径:

window.location.href.replace(/\/\w+\.\w+$/gi, "");

(3)split()方法

var sColor = "red,blue,yellow,green";
var reCom = /\,/ ; //因为","是正则表达式的元字符,所以用"\"来转义
var arrColors = sColor.split(reCom);

上面方法的效果等同于

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

(4)search(expr),返回字符串中与expr相匹配的第一个匹配的index值。

var regx=/user\d/g;   
var str=“user13userddduser345”;   
var rs=str.search(regx);//0

[b]三、简单模式[/b]

(1)元字符。

正则表达式的所有元字符如下:
( [ { \ ^ $ | ) ? * + .
任何正则表达式要使用元字符,都必须转义:
var reTest = /\?/ ;
或者:
var reTest = new RegExp("\\?"); //注意:是两个反斜杠,为了避免js像处理 \n 一样处理 \? ,

必须双重转义。

如果删除字符串中的所有换行符,如下:
var sNewStr = sOldStr.replace(/\n/g,"");

(2)字符类:

<1>.简单类 使用[abc] ,表示匹配中括号内的字符
var reTest = /[abc]at/gi; //匹配串中'at'字符前是'a'或者'b'或者'c'
例如:


var sTomatch = "a bat, a Cat, a fAt baT, a faT cat";
var reAt = /[abc]at/gi;
var arrMatches = sTomatch.match(reAt);
alert(arrMatches); //outputs 'bat, Cat, baT, cat';

<2>.反向类 使用[^abc],表示不匹配中括号内的字符
var reTest = /[abc]at/gi; //匹配串中'at'字符前不是'a'不是'b'不是'c'

例如:

var sTomatch = "a bat, a Cat, a fAt baT, a faT cat";
var reAt = /[^abc]at/gi;
var arrMatches = sTomatch.match(reAt);
alert(arrMatches); //outputs 'fAt,faT';

<3>.范围类 [a-z] ,表示匹配a到z范围之间的
例如:

var sTomatch = "num1,num2,num3,num4,num5";
var reAt = /num[1-3]/g;
var arrMatches = sTomatch.match(reAt);
alert(arrMatches); //outputs 'num1,num2,num3';

<4>.组合类 [a-z1-4\n] 标识匹配所有a~z,1~4 以及一个换行符
例如:

var sTomatch = "num1,numanuma,numb,num4,num5,num\nnum3numt,num9";
var reAt = /num[1-3a-m\n]/g;
var arrMatches = sTomatch.match(reAt);
alert(arrMatches); //outputs 'num1,numa,numa,numb,num?,num3';

<5>.预定义类 由于经常用到一些模式,正则表达式预定义了一些常用匹配:如下:

. [^\n\r] 除了换行和回车之外的任意字符
\d [0-9] 数字
\D [^0-9] 非数字
\s [ \r\n\x0B\f\r] 空白字符
\S [^\r\n\x0B\f\r] 非空白字符
\w [a-zA-Z_0-9] 单词字符(所有的字母、数字、下划线)
\W [^a-zA-Z_0-9] 非单词字符


<6>.简单量词,如下表:

^ 匹配输入字符串的起始端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符后匹配


$ 匹配输入字符创的尾端,如果是多行匹配,即表达式的附加参数中含有m,则也在一个换行符前匹配。
? 出现零次或一次
* 出现零次或多次(任意次)
+ 出现一次或多次(至少出现一次)
{n} 一定出现n次
{n,m} 至少出现n次,但不超过m次
{n,} 至少出现n次

例子:/^B/匹配 “Bab Bc ”中的第一个B
例子2:/^B/gm匹配
 “Badd B
  cdaf
  B dsfB”
中的第一行第一个B,第三行中的第一个B

<7>.捕获性分组 (x):表示匹配x(并非特指字符x或者特指一个字符,x表示一个字符串),而且匹配会被记住,在语法

中这种()被称为“capturing parentheses ”,即捕捉用的小括号。
  匹配会被记住,是因为在表达式提供的函数中,有些函数返回一个数组,该数组会保存所匹配的所有

字符串,例如exec()函数。
  另外还要注意()中的x被记住的前提是匹配x。
  例子1:
  
var regx=/a(b)c/;
  var rs=regx.exec("abcddd");

  从上面可以看出,/a(b)c/匹配“abcddd”中的“abc”,因为()的原因,b也会记录下来,因此rs返回的数字内容为: 数组:[abc,b]
  例子2:
  var regx=/a(b)c/;
  var rs=regx.exec(“acbcddd”);
  rs返回null,因为/a(b)c/不匹配“acbcddd”,所以()中的b不会被记录下来(尽管字符串中含有b)
<8>.非捕获性分组 (?:x):匹配x,但不会记住x,这种格式中的()被称为“non-capturing parentheses ”,即非捕捉用的小括号。
  例子:
  
var regx=/a(?:b)c/;
  var rs=regx.exec("abcddd");

  从上面可以看出,/a(?:b)c/匹配“abcddd”中的“abc”,因为(?:)的原因,b不会记录下来,因此rs返回的数字内容为: {abc}
<9>X(?=y):匹配x,仅当后面紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
  例子:
  
var regx=/user(?=name)/;
  var rs=regx.exec("The username is Mary");

  结果:匹配成功,而且rs的值为{user}

//正向前瞻
re = /([a-z]+(?=\d))/i;
//我们要匹配后面跟一个数字的单词,然后将单词返回,而不要返回数字
str = "abc every1 abc";
alert(re.test(str));//true
alert(RegExp.$1);//every
alert(re.lastIndex);//使用前瞻的好处是,前瞻的内容(?=\d)并不会当成一次匹配,下次匹配仍从它开始

<10>.X(?!y):匹配x,仅当后面不紧跟着y时。如果符合匹配,则只有x会被记住,y不会被记住。
  例子:
  
var regx=/user(?!name)/;
  var rs=regx.exec("The user name is Mary");

  结果:匹配成功,而且rs的值为{user}
  例子2:
  
var regx=/\d+(?!\.)/;
  var rs=regx.exec("54.235");

  结果:匹配成功,rs的值为{5},不匹配54是因为54后面跟着“.”号,当然235也匹配,但是由于exec方法的行为,235不会被返回

//负向前瞻(?!)
re = /([a-z](?!\d))/;i
//将匹配后面不包含数字的字母,并且不会返回(?!\d)中的内容
str = "abc1 one";
alert(re.test(str));
alert(RegExp.$1);//one

<11>.x|y:匹配x或y。注意如果x和y都匹配上了,那么只记住x。
  例子:
  
var regx=/beijing|shanghai/;
  var rs=regx.exec("I love beijing and shanghai");

  结果:匹配成功,rs的值为{beijing},虽然shanghai也匹配,但不会被记住。
[b]四、表达式相关属性[/b]
1)表达式相关属性,是指和表达式相关的属性,如下面的形式:
  var regx=/myexpr/;
  var rs=regx.exec(str);
  其中,和表达式自身regx相关的属性有两个,和表达式匹配结果rs相关的属性有三个,下面将逐一介

绍。

2)和表达式自身相关的两个属性:

1> lastIndex,返回开始下一个匹配的位置,注意必须是全局匹配(表达式中带有g参数)时,lastIndex

才会有不断返回下一个匹配值,否则该值为总是返回第一个下一个匹配位置,例如:

  var regx=/user\d/;
  var rs=regx.exec(“sdsfuser1dfsfuser2”);
  var lastIndex1=regx.lastIndex;
  rs=regx.exec(“sdsfuser1dfsfuser2”);
  var lastIndex2=regx.lastIndex;
  rs=regx.exec(“sdsfuser1dfsfuser2”);
  var lastIndex3=regx.lastIndex;
  
上面lastIndex1为9,第二个lastIndex2也为9,第三个也是9;如果regx=/user\d/g,则第一个为9,第二个为18,第三个为0。

2> source,返回表达式字符串自身。例如:
  
var regx=/user\d/;
  var rs=regx.exec("sdsfuser1dfsfuser2");
  var source=regx.source;
  source的值为user\d

3)和匹配结果相关的三个属性:
1> index,返回当前匹配的位置。例如:
  var regx=/user\d/;
  var rs=regx.exec(“sdsfuser1dfsfuser2”);
  var index1=rs.index;
  rs=regx.exec(“sdsfuser1dfsfuser2”);
  var index2=rs.index;
  rs=regx.exec(“sdsfuser1dfsfuser2”);
  var index3=rs.index;
  index1为4,index2为4,index3为4,如果表达式加入参数g,则index1为4,index2为13,index3会

报错(index为空或不是对象)。

2> input,用于匹配的字符串。例如:
  
var regx=/user\d/;
  var rs=regx.exec("sdsfuser1dfsfuser2");
  var input=rs.input;
  input的值为sdsfuser1dfsfuser2。

3> [0],返回匹配结果中的第一个匹配值,对于match而言可能返回一个多值的数字,则除了[0]外,还可

以取[1]、[2]等等。例如:
  var regx=/user\d/;
  var rs=regx.exec("sdsfuser1dfsfuser2");
  var value1=rs[0]; //user1

3)leftContext 返回被查找的字符串中从字符串开始位置到最后匹配之前的位置之间的字符;
rigthContext 返回被搜索的字符串中从最后一个匹配位置开始到字符串结尾之间的字符 。

re = /[A-Z]/g;
str = "123ABC456";
re.test(str);
alert(RegExp.leftContext);//123
alert(RegExp.rightContext);//BC456
re.test(str);
alert(RegExp["$`"]);//123A
alert(RegExp["$'"]);//C456

4)lastParen 最后匹配的分组

re = /[a-z](\d+)/gi;
str = "Class1 Class2 Class3";
re.test(str);
alert(RegExp.lastParen);//1
re.test(str);
alert(RegExp["$+"]);//2

5)lastMatch 最后匹配的字符

re = /[a-z]/g;
str = "hi";
re.test(str);
alert(RegExp.lastMatch);//h
re.test(str);
alert(RegExp["$&"]);//i ,$&是lastMatch的短名字

6)反向引用

var re = /(A?(B?(C?)))/;
/*上面的正则表达式将依次产生三个分组
(A?(B?(C?))) 最外面的
(B?(C?))
(C?)*/
str = "ABC";
re.test(str);//反向引用被存储在RegExp对象的静态属性$1—$9中
alert(RegExp.$1+"\n"+RegExp.$2+"\n"+RegExp.$3);
//反向引用也可以在正则表达式中使用\1 ,\2...这类的形式使用
re = /\d+(\D)\d+\1\d+/;
str = "2008-1-1";
alert(re.test(str));//true
str = "2008-4_3";
alert(re.test(str));//false


re = /(\d+)\s(\d+)/;
str = "1234 5678";
alert(str.replace(re,"$2 $1"));//在这个里面$1表示第一个分组1234,$2则表示5678

[b]五、例子[/b]

/*
* 描述:有一表单,其中有一个“用户名”input域
* 要求:汉字,而且不能少于2个汉字,不能多于4个汉字。
*/
function checkForm(obj){   
var username=obj.username.value;   
var regx=/^[\u4e00-\u9fa5]{2,4}$/g   
if(!regx.test(username)){   
alert(“Invalid username!”);
   return false;   
}   
return true;
}

/*
* 描述:给定一个含有html标记的字符串,要求将其中的html标记去掉。
*/
function toPlainText(htmlStr){   
var regx=/<[^>]*>|<\/[^>]*>/gm;   
var str=htmlStr.replace(regx,"");   
return str;
}

/*
*去掉前后空格
*/
function trim(str){
return str.replace(/^(\s+)|(\s+)$/g, "");
}

/**
* 取传给html页面的参数
*/
var href=String(window.document.location.href);

function getArgsFromHref(href, str){
var rs = new RegExp("(^|)"+str+"=([^\&]*)(\&|$)","gi").exec(href);

if(rs){
return rs[2];
}

return "";
}

/**
*从文件路中取出“目录”、“文件名”、“扩展名”
*@param path
* 文件路径
*@param type
1:路径,2:文件名,3:扩展名
**/
function parseFilePath(path,type){
var regExp = /(.+\/)(\w+)[\.\w+]*\.(\w+)$/g;
if(!regExp.test(path)) return "";

var ret = "";
switch(type){
case '2':
ret = path.replace(reg, "$2");
break;
case '3':
ret = path.replace(reg, "$3");
break;
default: ret = path.replace(reg, "$1");
}
return ret;
}

/*
** 取指定字符串的长度
*/
function strLengthB(str){
var len = 0;
for(var i = 0; i < str.length; i++) {
if(/[\u4E00-\u9FA5\uF900-\uFA2D\uFF00-\uFFEF\u3000-\u303F]/.test(str.charAt(i)))
len = len + 2;
else
len = len + 1;
}

return len;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值