正则表达式学习

正则非常强大,进入学习之旅。
 
匹配模式:
g:进行全局匹配。找到所有匹配,而不是第一个就终止
i:不区分大小写
m:代表多行匹配,^和$不但匹配字符串的开头和结尾,而且匹配每行的开头的结尾。
 
简单的转义字符:
\r, \n代表回车和换行符
\t制表符
\\代表 "\" 本身
例如\.表示.本身。
例子:s=a$bc ,req=\$b 则s=a-c
 
 
多种字符匹配:
\s任何空白字符
\S任何非空白字符
\d匹配一个数字字符,相当于[0-9]
\D匹配一个非数字字符,相当于[^0-9]
\w匹配一个数字、下划线或字母字符,等价于[a-zA-Z0-9_]
\W匹配一个非数字、下划线或字母字符,等价于[^a-zA-Z0-9_]
        [\b]          退格键。特例,用于字符串中,后面将看到\b的特殊用途,所以匹配退格键的时候使用[\b]
.除了换行符之外的任意字符
例子:s=a123c ,req=\d 则s=a---c
例子:  去除script标签,s=<script type=abc> uiolk </script>, req=<script[\s\S]*>[\s\S]*</script>,则s=-。
也可以把[\s\S]*换成.*但是就不能替换换行符了
 
 
自定义的多种字符匹配:
[ab5@]匹配 "a" 或 "b" 或 "5" 或 "@"
[^abc]匹配 "a","b","c" 之外的任意一个字符
[f-k]匹配 "f"~"k" 之间的任意一个字母
[^A-F0-3]匹配 "A"~"F","0"~"3" 之外的任意一个字符
这个很好理解,参考上面的例子。
 
 
修饰匹配次数的特殊符号:
{n}表达式重复n次,比如: "\w{2}" 相当于 "\w\w"; "a{5}" 相当于 "aaaaa"
{m,n}表达式至少重复m次,最多重复n次,比如: "ba{1,3}"可以匹配 "ba"或"baa"或"baaa"
{m,}表达式至少重复m次,比如: "\w\d{2,}"可以匹配 "a12","_456","M12344"...
?匹配表达式0次或者1次,相当于 {0,1},比如: "a[cd]?"可以匹配 "a","ac","ad"
+表达式至少出现1次,相当于 {1,},比如: "a+b"可以匹配 "ab","aab","aaab"...
*表达式不出现或出现任意次,相当于 {0,},比如: "\^*b"可以匹配 "b","^^^b"...
例子:表达式 "\d+\.?\d*" 在匹配 "It costs $12.5" 时,匹配的结果是:成功;匹配到的内容是:"12.5"
表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时,匹配的结果是:成功;匹配到的内容是:"goooooogle"
 
 
选择:
|左右两边表达式之间 "或" 关系,匹配左边或者右边
()(1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
(2). 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到
例子:表达式 "Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时,匹配结果是:成功;匹配到的内容是:"Tom"
表达式 "(go\s*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go"
表达式 "¥(\d+\.?\d*)" 在匹配 "$10.9,¥20.5" 时,匹配的结果是:成功
 
 
匹配次数中的贪婪与非贪婪:
贪婪模式表示正则总是想匹配更多的字符,而非贪婪意思相反。
贪婪模式:对于字符串 "dxxxdxxxd,对应测试如下:
 (d)(\w+)"\w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd"
 (d)(\w+)(d)"\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。
虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"\w+" 可以 "让出" 它本来能够匹配的最后一个 "d"
非贪婪:在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。
(d)(\w+?)"\w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"\w+?" 只匹配了一个 "x"
(d)(\w+?)(d)为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。
因此,结果是:"\w+?" 匹配 "xxx"
例子:表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配时,匹配的结果是:成功。但是这个匹配是贪婪模式,一直到最后的</td>
相比之下,表达式 "<td>(.*?)</td>" 匹配举例1中同样的字符串时,将只得到 "<td><p>aa</p></td>", 
再次匹配下一个时,可以得到第二个 "<td><p>bb</p></td>"。
 
 
反向引用\1,\2:
        允许同一个正则的后部引用前面的子表达式。
前面有小括号的应用,当要获取的内容不包含边界时,必须用小括号指定所要的范围,比如<td>(.*?)</td>.
对于小括号的引用,我们可以可以指定第几个括号可以重复使用。例如s = "'Hello',\"World\"",我们的匹配式req = /('|")(.*?)\1/;(注意后面的"\1"),
得到的结果是-,"World"。我们看到('|")匹配了hello前面的单引号,(.*?)中*表示0到多次,而?表示非贪婪模式,也就是说这个表达式表示的意思是0次,什么都没有。
后面"\1"很关键,他的意思是我引用了第一个括号中的表达式(即重复的意思),那么整个表达式就可以翻译为('|")(.*?)('|")。
如果我们这样写:req = /('|")(.*?)\2/;那么它的真实含义是req = /('|")(.*?)(.*?)/;,结果为-Hello',"World"。
需要注意的是,哪一对的左括号 "(" 在前,那这一对就先排序号。例如;"<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>"其中的"\4"表示的是('|")的内容。
例子:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,得到的结果是ccccc,第二次是999999999. 注意与 "\w{5,}" 之间的区别。
        还有个有趣的例子,括号引用的匹配: /['"][^'"]['"]/    但是这种匹配不能保证前后的括号一致,可以这样做:/[(['"])[^'"]\1]/  。那如果这样写:/(['"])[^\1]\1/,表示的意义又有不同了
        
        同样,如果我们不想让括号参见引用,可以使用分组,例如:/([jJ]ave(?:[sS]cript)?)\sis\s(fun\w*)/。子表达式(?:[sS]cript)仅仅用于分组,所以\2引用的是(fun\w*)。
 
 
指定位置(锚元素):
        ^ 与字符串开始的地方匹配,不匹配任何字符(用在自定义字符匹配中,是"非"的意思)
        $ 与字符串结束的地方匹配,不匹配任何字符
        (?= ... )        零宽正向先行断言:圆括号的表达式必须正确匹配。例如/(script)?(?=\:)/,可以匹配"javascript:"中的"script",但不匹配"java script wow"中的script。冒号必须存在。
        (?! ...)           零宽负向先行断言,要求接下来的字符不与内容匹配。例如:/Java(?!Script)([A-Z]\w*)/,可以匹配 JavaBean,但不能匹配 Javanese。可以匹配 JavaAbc,但不能匹配 JavaScript。
        \b 匹配一个单词边界,即位于\w字符和\W之间的边界,或位于一个ASCII单词与字符串的开始或结尾之间的边界。
例子: 表达式 "^aaa" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。必须以aaa开头
表达式 "aaa$" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。必须以aaa结束

          表达式 "\bend\b" 在匹配 "weekend,endfor,end" 时,匹配结果是:成功。匹配到的内容是:"end";匹配到的位置是:开始于15,结束于18。

表达式 ".\b." 在匹配 "@@@abc" 时,匹配结果是:成功;匹配到的内容是:"@a"
进一步说明:"\b" 与 "^" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,
其中一边是 "\w" 范围,另一边是 非"\w" 的范围。
        
 
补充:
表达式中,可以使用 "\xXX" 和 "\uXXXX" 表示一个字符("X" 表示一个十六进制数)
\xXX编号在 0 ~ 255 范围的字符,比如: 空格可以使用 "\x20" 表示
\uXXXX任何字符可以使用 "\u" 再加上其编号的4位十六进制数表示,比如: "\u4E2D"
 
在表达式 "\s","\d","\w","\b" 表示特殊意义的同时,对应的大写字母表示相反的意义
\S匹配所有非空白字符("\s" 可匹配各个空白字符)
\D匹配所有的非数字字符
\W匹配所有的字母、数字、下划线以外的字符
\B匹配非单词边界,即左右两边都是 "\w" 范围或者左右两边都不是 "\w" 范围时的字符缝隙
 
 
 
用于模式匹配的String方法:
 
    search()        "abc".search(/\s*/ig)    返回搜索到的索引位置
    replace()        text.replace(/\W/g,"")    替换,第一个参数是正则,第二个是要替换为的内容。 值得注意的是,replace()方法的第二个参数可以是函数,用以动态替换字符串。
    match()         唯一参数是一个正则,返回一个由匹配结果组成的数组。如果使用修饰符g,则返回所有匹配结果。如果不使用g,则只检索第一个匹配,但也是返回一个数组。因此,如果match()返回一个数组a,那么a[0]存放的是完整的匹配,a[1]存放的则是与第一个用圆括号括起来的表达式相匹配的子串。
     split()        参数可以是字符,也可以是正则。
 
 
 
RegExp对象:

    RegExp对象构造函数有两个参数,第二个是可选的:new RegExp("\s*","g");
    5个属性: 
        source    正则表达式的文本
        global    是否带有修饰符 g
        ignoreCase    
        multiline    
        lastIndex    一个可读写的整数,如果匹配模式带有g 修饰符,这个属性存储在整个字符串中下一次检索的开始位置,这个属性被exec()和test()方法用到。
    exec()        和String.match()相似。在字符串中执行匹配检索,没有匹配返回null,否则返回数组。这个数据和match()方法为非全局检索返回的数组一样,第一个元素包含于正则表达式匹配的字符串,余下的元素是与圆括号内的子表达式相匹配的子串。属性index包含了发生匹配的字符位置,属性input引用的是正在检索的字符串。
                    和match()不同,不管正则是否由全局修饰符g,exec()都返回一样的数组。match()中有全局正则时,返回匹配结果组成的数组。相比之下,exec()总返回一个匹配结果,并提供完整信息。这样就用到了lastIndex,可以多次调用exec()方法;                
    test()        对某个字符串进行检测,如果包含匹配结果,则返回true。

    调用test()和exec()等价,因为他们从lastIndex指定位置开始检索某个字符串。

 
    

 

 

 

posted @ 2013-04-25 10:57  轩辕李  阅读(206)  评论(0编辑  收藏  举报