正则

正则用的很普遍,本文仅针对JavaScript。

创建

有两种方式:

1. new RegExp('表达式', '匹配模式'),这种方式的表达式中如果需要转义,转义符需要写两个,如 '\\d'

2. 直接量


常用属性

1. $1 -> $9

返回9个在模式匹配期间找到的,最近保存的部分,只读

2. index

返回第一次成功匹配的开始位置,只读

3. lastIndex

返回最后一次成功匹配的结束位置(下一次匹配开始的位置),可读写。

只有当使用exec() 或 test() 时才会写入。

4. lastMatch

返回最后匹配的字符,只读。

5. input

返回查找的字符,只读。

这里先送上一个例子,我第一次做的时候觉得异常诡异。

var r = /\d/g;
 
alert(r.test('abcd')); // false
alert(r.lastIndex); // 0
 
alert(r.test('ab1')); // true
alert(r.lastIndex); // 3
 
alert(r.test('a1')); // false
alert(r.lastIndex); // 0

说明: lastIndex属性实例属性,当一个正则表达式实例多次test或exec时,它的lastIndex每一次都将被改写。

 

查找

1. 找出 "~!ab@cd#12$%e3^" 中的数字和字母

  第一反应,数字应该是[0-9],字母应该是[a-zA-Z]

  但是呢,元字符\w其实就能兼顾二者,来看下 

var str = '~!ab@cd#12$%e3^', rep = /\w+/g;
str.match(rep);
//输出 ["ab", "cd", "12", "e3"]


2. 取出 '<a href="http://g.cn">Google</a>' 中的标签,不要innerHTML,即结果为<a href="http://g.cn"></a>

  因为是成对出现的,所以需要记住开头匹配的标签名,这里要用到\1, \2这样的索引,表示第一、二个括号匹配的文本

var str = '<a href="http://g.cn">Google</a>',
	rep = /(<(\w+)[^>]*>)[^<]*(<\/\2>)/g;
if(rep.test(str)){
	RegExp.$1;
	RegExp.$3;
}

  $1 和 $3,表示正则第一个和第三个括号匹配的内容。 


3. 紧接着第2题,取出 '<a href="http://g.cn">Google</a>' 中的innerHTML

var str = '<a href="http://g.cn">Google</a>',
	rep = /<(\w+)[^>]*>([^<]*)<\/\1>/g;
if(rep.test(str)){
    RegExp.$2
}

 
4. JS只支持正序环视,而不支持逆序环视

var str = 'jsafter', rep = /js(?=after)/g;
rep.exec(str);

  如果 str 换成 "jsbefore",就会匹配失败,但是我们可以这么做

var str = 'jsbefore', rep = /js(?!after)/g;
rep.exec(str);


5. 非捕获性分组

var str = '#12345', rep = /#(?:\d+)/;
if (rep.test(str)) {
    RegExp.$1;
}

 

6. 神奇的match()方法

var str = 'js1', rep = /(js)1/;
str.match(rep);

  这样会打印出 ['js1', 'js'],如果正则加上g,也就是全局匹配,则会打印 ['js1']

 

 

替换

替换常用replace()方法,如果它的第一个参数是正则表达式,则第二个参数是函数。

如果正则存在反向引用时,函数的参数列表为:

  arguments[0]:成功匹配的字符串

  arguments[1]:$1

  arguments[2]:$2

  .......

  arguments[arguments.length - 2]:匹配到的位置

  arguments[arguments.length - 1]:要匹配的字符串


如果正则不存在反向引用,函数的参数列表为:

  arguments[0]:成功匹配的字符串

  arguments[1]:匹配到的位置

  arguments[2]:要匹配的字符串

 

1. 把 "<a>g</a>" 替换成 "<b>g</b>"

var str = '<a>g</a>',
	rep = /<(\w+)[^>]*>([^<]*)<\/\1>/g;
str.replace(rep, '<b>$2</b>');


2.  "1废话2废话3废话4废话5废话...",...表示无限可能,任意字符,现在需要把第三个"废话"后面的全部删除

var str = '1废话2废话3废话4废话5废话...',
	rep = /(.*?废话){3}/g;
str = str.match(rep)[0];

 

3. 把类似 0011.0100 前面的、后面的0去掉(特殊情况 .01, 0.01,记得试试这两个)

  先分成整数部分和小数部分进行处理

  整数可能出现的情况有:

    1. n个0开头,然后数字结尾,如001、0010、10、0

    2. 空字符,即整体为 .1 的形式

  这样的话,我们先看开头的部分,正则应该是0*?,后面的部分怎么处理呢?它可能是0-9中的任何数字。

  也许有人会写成\d*,但这样明显不对,如果这个数字是012呢,这个0应该算在开头的正则中,所以继续分类处理:

    1. 只有1位数字时,\d

    2. 大于1位数字时,[1-9]\d+

    3. 这种情况比较特殊,比如 .1,开头的0没匹配上,在这个部分就必须考虑这种情况了,其实就是\d?

  合并一下,就是 (\d?|[1-9]\d+),上述整理合并就是0*?(\d?|[1-9]\d+)


  接着看小数部分,\.\d+ 这是最原始的正则,如果是.0100的情况,我们只需要.01,后面的0都要去掉,所以该这么写:(\.\d+?)0*。因为小数部分是可有可无的,所以最后应该写成 ((\.\d+?)0*)?

 

var str = '001.0100', rep = /^0*?(\d?|[1-9]\d+)((\.\d+?)0*)?$/g;
rep.test(str);
RegExp.$1;
RegExp.$3;

  

posted @ 2012-01-09 10:55  越己  阅读(434)  评论(0编辑  收藏  举报