js正则表达式

在线正则测试:http://regexpal.com/

一点的学习,关于正则的会都放在这里:

基础知识:

特殊的元字符/保留字符:正则表达式中不参与匹配的字符,如[],()

量词:如+,*,?,{3},{3,}里的3,{3,6}

字符组简写式/转义字符:如\d

捕获分组:用( )括起来,后面可以用\1对捕获的内容进行后向引用,如(\d)\d\1匹配三个数字,且第一位和第二位数字相同

非捕获分组:(?:pattern),匹配pattern但是不保存捕获内容,(?:t|T)(\d)\1匹配t11而不是t1t

量词贪心:默认会尽量多的匹配。量词首次尝试匹配整个字符串,若失败则回退一个字符再尝试(这个过程叫回溯),每次回退一个字符直到找到匹配内容或没有字符可以回退了。如a{1,3}会匹配baaab中的aaa;

量词懒惰/勉强:量词后加?,从目标的起始位置开始寻找匹配,每次检查一个字符,若失败则前进一位直到尝试匹配整个字符串。a{1,3}?会匹配baaab中的a和a和a;

 

/.../g: global

/.../i: ignoreCase

/.../m: multiline,没有m时,整个目标文本被当作一个字符串,^只匹配最开始的一个地方,/.../m时,^匹配每一行的开始。

/.../gsm: s:表示.除了匹配其他字符外,还匹配换行符\n

[1-3]

[369]

[,;]

\d,\D

[^0-9]

\w,\w

\s,\S

\b

\B

.

{3}

?

|:注意a|bc和(a|b)c的区别

^

$

1、关于\b

\b:匹配一个单词边界,除了空格外,“-”、“/”、“.”、“;”、“,”、“《”等标点符号都被当做单词边界(下划线‘_'不能界定边界),

如'ab_c-d;8<e f.g/h'.replace(/\b(\w)\b/g, '0$1')的结果是:ab_c-0d;08<0e 0f.0g/0h  (注意最后一个h也被替换了,因为最开头和最后面默认有一个边界);

又如把2009-8-5转换成2009-08-05,可以‘2009-8-5'.replace(/\b(\d)\b/g, '0$1')=='2009-08-05'

2、关于\B

\B:匹配非单词边界。

"123456789".replace(/\d{3}\B/g,function(s){return s+',';});------"123,456,789"
"123456789".replace(/\B\d{3}/g,function(s){return s+',';});------"1234,567,89";

3、关于^和$

这两个分别匹配字符串的开始位置和结束位置。如/4$/表示要以4结尾;/^4$/则只匹配4,像434不匹配。

4、关于匹配汉字

/[\u4e00-\u9fa5]/表示匹配汉字,如把字符串a中所有汉字换成’-‘:a.replace(/[\u4e00-\u9fa5]/g,'-');检验字符串a中是否全是汉字:不是/^[\u4e00-\u9fa5]$/.test(a);这只会匹配一个汉字,应该是/^[\u4e00-\u9fa5]+$/.test(a);

5、关于$1...$9

RegExp对象的$1...$9属性是只读的,如果表达式模式中有括起来的子匹配,$1…$9属性值分别是第1个到第9个子匹配所捕获到的内容。如果有超过9个以上的子匹配,$1…$9属性分别对应最后的9个子匹配。如/^(\d{3,4})-(\d+)$/.test('079-8778');alert(RegExp.$1);alert(RegExp.$2);分别为079和8779.

如实现一个如下功能的函数:把1转换成‘1’,把1转换成‘12’,把1转换成‘12’,把1转换成‘123’,把1转换成‘123’,把1234转换成‘1,234’,把12345转换成‘12,345’,......把12345678转换成‘12,345,678’, 

function groupByCommas(n) {
  var n=n.toString();
  if((n.length<7)&&(n.length>3)) return n.replace(/(\d{3}$)/g,",$1");
  else{
    switch(n.length%3){
      case 1:  return n.replace(/(^\d{1})(\d{3}\B)/g,"$1,$2,");
      case 2:  return n.replace(/(^\d{2})(\d{3}\B)/g,"$1,$2,");
      default: return n.replace(/(^\d{3})(\d{3}\B)/g,"$1,$2,")
    }
  }
}

 上面这种做法不对的,会把1234567890转换成‘1,234,567890’,下面的正确。

function groupByCommas(n) {
  var n=n.toString();
  if(n.length<3) return n;
  else{
    switch(n.length%3){
      case 1:  return n.replace(/(^\d{1})/g,"$1,").replace(/(\d{3}\B)/g,"$1,");
      case 2:  return n.replace(/(^\d{2})/g,"$1,").replace(/(\d{3}\B)/g,"$1,");
      default: return n.replace(/(\d{3}\B)/g,"$1,")
    }
  }
}

 更好更简洁的方法如下:

function groupByCommas(n) {
  return n.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}

\Bxxx表示xxx不是在边界开始的地方;

+表示重复至少一次;

():在被修饰匹配次数的时候,括号中的表达式表示作为整体被修饰;在取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到;

\d表示0-9中的任意一个;

{3}表示重复3次;

(?=xxx)表示前面字符的右边必须匹配xxx,可以理解为这只是这个缝隙的后面要匹配的内容,不影响xxx继续匹配正则表达式后面的内容。

如/window(?=NT|XP)/g只匹配'windowNTwindow7'中的window,而不是匹配windowNT,

(?!xxx)表示前面字符的右边必须不匹配xxx,同样不影响xxx继续匹配正则表达式后面的内容。

综上,/\B(?=(\d{3})+(?!\d))/g表示一个缝隙,不是单纯开始的缝隙,此缝隙右边必须有3个数字(这3个数字可以出现一次或多次),接着不能出现数字,也就是缝隙右边只能出现3的倍数个数字。

或者

str.replace(/(\d)(?=(\d{3})+(\.\d+)?$)/g,'$1,')

/(\d)(?=(\d{3})+(\.\d+)?$)/g表示匹配一个数字,这个数字后面要么的多组\d{3}结尾要么是多组\d{3}后跟着一个小数点和多位数字结尾。

或者

str..replace(/\B(\d{3})(?=(\d{3})*(\.\d+)?$)/g,',$1')

/\B(\d{3})(?=(\d{3})*(\.\d+)?$)/gb表示匹配一个三位数字,且不是最开头的三位数字,这三位数字后面要么啥也没有,要么后面是0组或多组\d{3},然后以一个小数点和多位数字结尾或是直接结尾。

补充内容:贪婪模式和非贪婪模式

如对于字符串“dxxxdxxxd”

/d(\w+)d/匹配完整的“dxxxdxxxd”,/d(\w+?)d/匹配完整的“dxxxd”。

贪婪模式:匹配次数尽可能多,

非贪婪模式:当在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式。

常用正则表达式:\b

只允许字母和空格: /^[a-zA-Z ]*$/
e-mail: /([\w\-]+\@[\w\-]+\.[\w\-]+)/
url: /\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i

计算匹配项出现的次数: 

//注意是全局模式//g
var p=/.cc/g,fullText='aaccbbccddcc';
p.exec(fullText);
//["acc"]
p.lastIndex;
//4
p.exec(fullText);
//["bcc"]
p.lastIndex;
//8
p.exec(fullText);
//["dcc"]
p.lastIndex;
//12
p.exec(fullText);
//null
p.lastIndex;
//0
p.exec(fullText);
//["acc"]
......

所以计算次数为:

var count=0;
while(p.exec(fullText)){count++;}
return count;

如果希望对字符串'bbaaacc'匹配'aa'的次数为3,则:

var count=0,searchText='aa',fullText='baaa';
var p=new RegExp(searchText,'g');//在正则表达式中引入变量的方法
while(p.exec(fullText)){p.lastIndex-=searchText.length-1;count++;}
return count;

 .replace(/.../,...)

$& Inserts the matched substring.
$` Inserts the portion of the string that precedes the matched substring.
$' Inserts the portion of the string that follows the matched substring.

例如:

'dabc'.replace(/a/,'11$&')--------"d11abc"

'dabc'.replace(/a/,'11$`')--------"d11dbc"

'dabc'.replace(/a/,"11$'")--------"d11bcbc"

也可以.replace(reg, function), function参数为(match, $1, $2,...)

如: 'a-bc-de'.replace(/[-_](\w)/g,(match,$1)=>{console.log(match);return $1.toUpperCase()})   // 'aBcDe'

posted @ 2014-10-17 16:07 荔枝龙眼 阅读(...) 评论(...) 编辑 收藏

这里是页脚Html代码