正则表达式语法
一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。这里有一些可能会遇到的正则表达式示例:JScript VBScript 匹配 
/^\[ \t]*$/ "^\[ \t]*$" 匹配一个空白行。 
/\d{2}-\d{5}/ "\d{2}-\d{5}" 验证一个ID 号码是否由一个2位数字,一个连字符以及一个5位数字组成。 
/<(.*)>.*<\/\1>/ "<(.*)>.*<\/\1>" 匹配一个 HTML 标记。 
下表是元字符及其在正则表达式上下文中的行为的一个完整列表:字符 描述 
\ 将下一个字符标记为一个特殊字符、或一个原义字符、或一个 后向引用、或一个八进制转义符。例如,'n' 匹配字符 "n"。'\n' 匹配一个换行符。序列 '\\' 匹配 "\" 而 "\(" 则匹配 "("。 
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 '\n' 或 '\r' 之后的位置。 
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 '\n' 或 '\r' 之前的位置。 
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 "z" 以及 "zoo"。 * 等价于{0,}。 
+ 匹配前面的子表达式一次或多次。例如,'zo+' 能匹配 "zo" 以及 "zoo",但不能匹配 "z"。+ 等价于 {1,}。 
? 匹配前面的子表达式零次或一次。例如,"do(es)?" 可以匹配 "do" 或 "does" 中的"do" 。? 等价于 {0,1}。 
{n} n 是一个非负整数。匹配确定的 n 次。例如,'o{2}' 不能匹配 "Bob" 中的 'o',但是能匹配 "food" 中的两个 o。 
{n,} n 是一个非负整数。至少匹配n 次。例如,'o{2,}' 不能匹配 "Bob" 中的 'o',但能匹配 "foooood" 中的所有 o。'o{1,}' 等价于 'o+'。'o{0,}' 则等价于 'o*'。 
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。刘, "o{1,3}" 将匹配 "fooooood" 中的前三个 o。'o{0,1}' 等价于 'o?'。请注意在逗号和两个数之间不能有空格。 
? 当该字符紧跟在任何一个其他限制符 (*, +, ?, {n}, {n,}, {n,m}) 后面时,匹配模式是非贪婪的。非贪婪模式尽可能少的匹配所搜索的字符串,而默认的贪婪模式则尽可能多的匹配所搜索的字符串。例如,对于字符串 "oooo",'o+?' 将匹配单个 "o",而 'o+' 将匹配所有 'o'。 
. 匹配除 "\n" 之外的任何单个字符。要匹配包括 '\n' 在内的任何字符,请使用象 '[.\n]' 的模式。 
(pattern) 匹配pattern 并获取这一匹配。所获取的匹配可以从产生的 Matches 集合得到,在VBScript 中使用 SubMatches 集合,在JScript 中则使用 $0…$9 属性。要匹配圆括号字符,请使用 '\(' 或 '\)'。 
(?:pattern) 匹配 pattern 但不获取匹配结果,也就是说这是一个非获取匹配,不进行存储供以后使用。这在使用 "或" 字符 (|) 来组合一个模式的各个部分是很有用。例如, 'industr(?:y|ies) 就是一个比 'industry|industries' 更简略的表达式。 
(?=pattern) 正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如, 'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。 
(?!pattern) 负向预查,在任何不匹配Negative lookahead matches the search string at any point where a string not matching pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始  
x|y 匹配 x 或 y。例如,'z|food' 能匹配 "z" 或 "food"。'(z|f)ood' 则匹配 "zood" 或 "food"。  
[xyz] 字符集合。匹配所包含的任意一个字符。例如, '[abc]' 可以匹配 "plain" 中的 'a'。  
[^xyz] 负值字符集合。匹配未包含的任意字符。例如, '[^abc]' 可以匹配 "plain" 中的'p'。  
[a-z] 字符范围。匹配指定范围内的任意字符。例如,'[a-z]' 可以匹配 'a' 到 'z' 范围内的任意小写字母字符。  
[^a-z] 负值字符范围。匹配任何不在指定范围内的任意字符。例如,'[^a-z]' 可以匹配任何不在 'a' 到 'z' 范围内的任意字符。  
\b 匹配一个单词边界,也就是指单词和空格间的位置。例如, 'er\b' 可以匹配"never" 中的 'er',但不能匹配 "verb" 中的 'er'。  
\B 匹配非单词边界。'er\B' 能匹配 "verb" 中的 'er',但不能匹配 "never" 中的 'er'。 
\cx 匹配由x指明的控制字符。例如, \cM 匹配一个 Control-M 或回车符。 x 的值必须为 A-Z 或 a-z 之一。否则,将 c 视为一个原义的 'c' 字符。  
\d 匹配一个数字字符。等价于 [0-9]。  
\D 匹配一个非数字字符。等价于 [^0-9]。  
\f 匹配一个换页符。等价于 \x0c 和 \cL。 
\n 匹配一个换行符。等价于 \x0a 和 \cJ。 
\r 匹配一个回车符。等价于 \x0d 和 \cM。 
\s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ \f\n\r\t\v]。 
\S 匹配任何非空白字符。等价于 [^ \f\n\r\t\v]。 
\t 匹配一个制表符。等价于 \x09 和 \cI。 
\v 匹配一个垂直制表符。等价于 \x0b 和 \cK。 
\w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]'。  
\W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]'。  
\xn 匹配 n,其中 n 为十六进制转义值。十六进制转义值必须为确定的两个数字长。例如, '\x41' 匹配 "A"。'\x041' 则等价于 '\x04' & "1"。正则表达式中可以使用 ASCII 编码。. 
\num 匹配 num,其中 num 是一个正整数。对所获取的匹配的引用。例如,'(.)\1' 匹配两个连续的相同字符。  
\n 标识一个八进制转义值或一个后向引用。如果 \n 之前至少 n 个获取的子表达式,则 n 为后向引用。否则,如果 n 为八进制数字 (0-7),则 n 为一个八进制转义值。 
\nm 标识一个八进制转义值或一个后向引用。如果 \nm 之前至少有is preceded by at least nm 个获取得子表达式,则 nm 为后向引用。如果 \nm 之前至少有 n 个获取,则 n 为一个后跟文字 m 的后向引用。如果前面的条件都不满足,若  n 和 m 均为八进制数字 (0-7),则 \nm 将匹配八进制转义值 nm。 
\nml 如果 n 为八进制数字 (0-3),且 m 和 l 均为八进制数字 (0-7),则匹配八进制转义值 nml。 
\un 匹配 n,其中 n 是一个用四个十六进制数字表示的 Unicode 字符。例如, \u00A9 匹配版权符号 (?)。 

解决方案 »

  1.   

    看一下php手册里的相关部分就可以了,而且不用掌握到很高深的地步,够用就行。
      

  2.   

    正则表达式,基本模式多数都是通用的,比如js,asp,perl posix,所,学会模式匹配,基本上可通用
    但各正则也有少数不同,使用时要注意相关规范
    难点是要记住匹配开关及返回个人使用中一个难点是对换行回车的匹配,各语言会有不同,比如.表示所有字符(换行除外)----包括所有字符的匹配是个难点.但不同的语言规范下是不同的!
    其他大致相同!正则表达式功能强大,看过的正则中,好象c#的功能最全!但一般而言,vbsciptb也够用学习正则,一是了相关规范,二是最好下个正则练习器,学写模式!php的正则最好写!print_r()相当直观!
      

  3.   

    大哥们,别贴手册啊
    还有,这里的贴主要是讨论和 普通的web开发中常用的一些正则。还是先从素材开始收集吧。
    1 在ide上用正则和正则模版来提速,这个有简单的,也有复杂的。说个小例子。//例如有编辑人员给出如下数据.(很遗憾,他没能写成xml,也很遗憾,我也不想用xsl来将这数据转成xml,再去解析xml生成我想要的代码)
    http://www.google.com  
    http://www.msn.com    
    http://www.yahoo.com  
    http://www.facebook.com  
    http://www.csdn.net  
    .
    ..
    ...
    //..假设有点多例如有1w个
    这时想想其转换成
    <table><tr>
      <td><a href = 'http://www.baidu.com'>baidu</td>
      <td><a href = 'http://www.msn.com'>msn</td>
      <td><a href = 'http://www.yahoo.com'>yahoo</td>
      <td><a href = 'http://www.facebook.com'>facebook</td>
      <td><a href = 'http://www.csdn.com'>csdn</td>
       ........
    </tr>
    </table>
    //如果,你不准备用手去写,也不准备去指责这个任务很垃圾,做这个干什么。 这时请考虑正则。。
    有空再想想,如何为每八行td两边加<tr>  </tr>
    每天聊一点,希望有家有兴趣的多指点指点。
      

  4.   

    随便回一下:
    二楼:贴手册很支持,但我觉得个人的想法和经验更有价值,手册是容易得到的东西,有些时候,你在开发中真实的体验也是很有价值的,这些东西交流出来,可以让大家在以后路走得很顺。
    三楼:好像什么都有手册吧,我发贴是希望大家在一起交流一下应用。 php也有手册,但好像这个论坛还有点人气,大家没有全看手册,有空也来聊聊天。
    五楼:够用就行,,,,,,这个怎么说呢?我现在对正则的理解也算是够用了,不信你出点题试试。别拿验证邮箱来吓我就行了,但我一直想,如何收集和整理我所知道的,让我很快的能利用一些应用,甚至是一些正则所能带来的服务。我看了看,还是有不少人有正则的问题的。。而且正则在有些时候,又特别有用,我现在用的模版程序,就是全部用正则实现的。感觉正则还是蛮好用的,特别是字符串处理到后期,懒得多想时,就用正则这类万精油的搞法来解决。
    fxs_2008  呵呵,我用通常用 mtrace 来调试正则。
      

  5.   

    替换字符为变量(在类中)
    http://topic.csdn.net/u/20080417/15/4a25d5dd-16a2-4dcc-b0fe-0068e0da6b34.htmlhtml元素属性分析,结构化
    http://topic.csdn.net/u/20080411/09/16ea750b-c5ca-4573-93ae-5b8f330d782c.html超链接,email析出
    http://topic.csdn.net/u/20080412/18/074a3a29-5698-40b8-b434-f84b6edbc0d6.html日志分析 正则表达式一例 详解
    http://topic.csdn.net/u/20080117/23/70236117-33b8-42a0-8077-951d4244bb68.html过来过去都是手册,说了你又不信.
      

  6.   

    借问请教一下,内容正则处理问题
    一、比如从网页上来的字符,首行缩进两字符,多作空行!如何删除?就是只留换行回符,或只留回车符,其他空白字符和非法字符删除?如何做!
    二、如何用正则删除非法字符(空白表示)或乱码字符?
    三、正则的能处理的字符编码,如果遇latin,utf8,gb2312,正则处理会有什么不同?
      

  7.   

    自己顶一下。
    顺便请问一下 。SysTem128 15楼的问题用手册如何解决。
    我很期待把问题解决。他的问题我还没有试过,最近也没有专门的时间去整这些。
      

  8.   


    首先 要 知道 语法:正则表达式规则
    1. 正则表达式规则1.1 普通字符    字母、数字、汉字、下划线、以及后边章节中没有特殊定义的标点符号,都是"普通字符"。表达式中的普通字符,在匹配一个字符串的时候,匹配与之相同的一个字符。    举例1:表达式 "c",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"c";匹配到的位置是:开始于2,结束于3。(注:下标从0开始还是从1开始,因当前编程语言的不同而可能不同)    举例2:表达式 "bcd",在匹配字符串 "abcde" 时,匹配结果是:成功;匹配到的内容是:"bcd";匹配到的位置是:开始于1,结束于4。
    1.2 简单的转义字符    一些不便书写的字符,采用在前面加 "\" 的方法。这些字符其实我们都已经熟知了。
    表达式
     可匹配
     
    \r, \n
     代表回车和换行符
     
    \t
     制表符
     
    \\
     代表 "\" 本身
     
        还有其他一些在后边章节中有特殊用处的标点符号,在前面加 "\" 后,就代表该符号本身。比如:^, $ 都有特殊意义,如果要想匹配字符串中 "^" 和 "$" 字符,则表达式就需要写成 "\^" 和 "\$"。
    表达式
     可匹配
     
    \^
     匹配 ^ 符号本身
     
    \$
     匹配 $ 符号本身
     
    \.
     匹配小数点(.)本身
     
        这些转义字符的匹配方法与 "普通字符" 是类似的。也是匹配与之相同的一个字符。    举例1:表达式 "\$d",在匹配字符串 "abc$de" 时,匹配结果是:成功;匹配到的内容是:"$d";匹配到的位置是:开始于3,结束于5。
    1.3 能够与 '多种字符' 匹配的表达式    正则表达式中的一些表示方法,可以匹配 '多种字符' 其中的任意一个字符。比如,表达式 "\d" 可以匹配任意一个数字。虽然可以匹配其中任意字符,但是只能是一个,不是多个。这就好比玩扑克牌时候,大小王可以代替任意一张牌,但是只能代替一张牌。
    表达式
     可匹配
     
    \d
     任意一个数字,0~9 中的任意一个
     
    \w
     任意一个字母或数字或下划线,也就是 A~Z,a~z,0~9,_ 中任意一个
     
    \s
     包括空格、制表符、换页符等空白字符的其中任意一个
     
    .
     小数点可以匹配除了换行符(\n)以外的任意一个字符
     
        举例1:表达式 "\d\d",在匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"12";匹配到的位置是:开始于3,结束于5。    举例2:表达式 "a.\d",在匹配 "aaa100" 时,匹配的结果是:成功;匹配到的内容是:"aa1";匹配到的位置是:开始于1,结束于4。
    1.4 自定义能够匹配 '多种字符' 的表达式    使用方括号 [ ] 包含一系列字符,能够匹配其中任意一个字符。用 [^ ] 包含一系列字符,则能够匹配其中字符之外的任意一个字符。同样的道理,虽然可以匹配其中任意一个,但是只能是一个,不是多个。
    表达式
     可匹配
     
    [ab5@]
     匹配 "a" 或 "b" 或 "5" 或 "@"
     
    [^abc]
     匹配 "a","b","c" 之外的任意一个字符
     
    [f-k]
     匹配 "f"~"k" 之间的任意一个字母
     
    [^A-F0-3]
     匹配 "A"~"F","0"~"3" 之外的任意一个字符
     
        [url=http://www.regexlab.com/zh/workshop.asp?pat=[bcd][bcd]&txt=abc123]举例1:表达式 "[bcd][bcd]" 匹配 "abc123" 时[/url],匹配的结果是:成功;匹配到的内容是:"bc";匹配到的位置是:开始于1,结束于3。    举例2:表达式 "[^abc]" 匹配 "abc123" 时,匹配的结果是:成功;匹配到的内容是:"1";匹配到的位置是:开始于3,结束于4。
    1.5 修饰匹配次数的特殊符号    前面章节中讲到的表达式,无论是只能匹配一种字符的表达式,还是可以匹配多种字符其中任意一个的表达式,都只能匹配一次。如果使用表达式再加上修饰匹配次数的特殊符号,那么不用重复书写表达式就可以重复匹配。    使用方法是:"次数修饰"放在"被修饰的表达式"后边。比如:"[bcd][bcd]" 可以写成 "[bcd]{2}"。
    表达式
     作用
     
    {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},比如:[url=http://www.regexlab.com/zh/workshop.asp?pat=a[cd]%3F&txt=a,c,d,ac,ad]"a[cd]?"可以匹配 "a","ac","ad"[/url]
     
    +
     表达式至少出现1次,相当于 {1,},比如:"a+b"可以匹配 "ab","aab","aaab"...
     
    *
     表达式不出现或出现任意次,相当于 {0,},比如:"\^*b"可以匹配 "b","^^^b"...
     
        举例1:表达式 "\d+\.?\d*" 在匹配 "It costs $12.5" 时,匹配的结果是:成功;匹配到的内容是:"12.5";匹配到的位置是:开始于10,结束于14。    举例2:表达式 "go{2,8}gle" 在匹配 "Ads by goooooogle" 时,匹配的结果是:成功;匹配到的内容是:"goooooogle";匹配到的位置是:开始于7,结束于17。
    1.6 其他一些代表抽象意义的特殊符号    一些符号在表达式中代表抽象的特殊意义:
    表达式
     作用
     
    ^
     与字符串开始的地方匹配,不匹配任何字符
     
    $
     与字符串结束的地方匹配,不匹配任何字符
     
    \b
     匹配一个单词边界,也就是单词和空格之间的位置,不匹配任何字符
     
        进一步的文字说明仍然比较抽象,因此,举例帮助大家理解。    举例1:表达式 "^aaa" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 "^" 要求与字符串开始的地方匹配,因此,只有当 "aaa" 位于字符串的开头的时候,"^aaa" 才能匹配,比如:"aaa xxx xxx"。    举例2:表达式 "aaa$" 在匹配 "xxx aaa xxx" 时,匹配结果是:失败。因为 "$" 要求与字符串结束的地方匹配,因此,只有当 "aaa" 位于字符串的结尾的时候,"aaa$" 才能匹配,比如:"xxx xxx aaa"。    举例3:表达式 ".\b." 在匹配 "@@@abc" 时,匹配结果是:成功;匹配到的内容是:"@a";匹配到的位置是:开始于2,结束于4。
        进一步说明:"\b" 与 "^" 和 "$" 类似,本身不匹配任何字符,但是它要求它在匹配结果中所处位置的左右两边,其中一边是 "\w" 范围,另一边是 非"\w" 的范围。    举例4:表达式 "\bend\b" 在匹配 "weekend,endfor,end" 时,匹配结果是:成功;匹配到的内容是:"end";匹配到的位置是:开始于15,结束于18。
        一些符号可以影响表达式内部的子表达式之间的关系:
    表达式
     作用
     
    |
     左右两边表达式之间 "或" 关系,匹配左边或者右边
     
    ( )
     (1). 在被修饰匹配次数的时候,括号中的表达式可以作为整体被修饰
    (2). 取匹配结果的时候,括号中的表达式匹配到的内容可以被单独得到
     
        举例5:表达式 "Tom|Jack" 在匹配字符串 "I'm Tom, he is Jack" 时,匹配结果是:成功;匹配到的内容是:"Tom";匹配到的位置是:开始于4,结束于7。匹配下一个时,匹配结果是:成功;匹配到的内容是:"Jack";匹配到的位置时:开始于15,结束于19。    举例6:表达式 "(go\s*)+" 在匹配 "Let's go go go!" 时,匹配结果是:成功;匹配到内容是:"go go go";匹配到的位置是:开始于6,结束于14。    举例7:表达式 "¥(\d+\.?\d*)" 在匹配 "$10.9,¥20.5" 时,匹配的结果是:成功;匹配到的内容是:"¥20.5";匹配到的位置是:开始于6,结束于10。单独获取括号范围匹配到的内容是:"20.5"。
    2. 正则表达式中的一些高级规则2.1 匹配次数中的贪婪与非贪婪    在使用修饰匹配次数的特殊符号时,有几种表示方法可以使同一个表达式能够匹配不同的次数,比如:"{m,n}", "{m,}", "?", "*", "+",具体匹配的次数随被匹配的字符串而定。这种重复匹配不定次数的表达式在匹配过程中,总是尽可能多的匹配。比如,针对文本 "dxxxdxxxd",举例如下:
    表达式
     匹配结果
     
    (d)(\w+)
     "\w+" 将匹配第一个 "d" 之后的所有字符 "xxxdxxxd"
     
    (d)(\w+)(d)
     "\w+" 将匹配第一个 "d" 和最后一个 "d" 之间的所有字符 "xxxdxxx"。虽然 "\w+" 也能够匹配上最后一个 "d",但是为了使整个表达式匹配成功,"\w+" 可以 "让出" 它本来能够匹配的最后一个 "d"
     
        由此可见,"\w+" 在匹配的时候,总是尽可能多的匹配符合它规则的字符。虽然第二个举例中,它没有匹配最后一个 "d",但那也是为了让整个表达式能够匹配成功。同理,带 "*" 和 "{m,n}" 的表达式都是尽可能地多匹配,带 "?" 的表达式在可匹配可不匹配的时候,也是尽可能的 "要匹配"。这 种匹配原则就叫作 "贪婪" 模式 。
        非贪婪模式:    在修饰匹配次数的特殊符号后再加上一个 "?" 号,则可以使匹配次数不定的表达式尽可能少的匹配,使可匹配可不匹配的表达式,尽可能的 "不匹配"。这种匹配原则叫作 "非贪婪" 模式,也叫作 "勉强" 模式。如果少匹配就会导致整个表达式匹配失败的时候,与贪婪模式类似,非贪婪模式会最小限度的再匹配一些,以使整个表达式匹配成功。举例如下,针对文本 "dxxxdxxxd" 举例:
    表达式
     匹配结果
     
    (d)(\w+?)
     "\w+?" 将尽可能少的匹配第一个 "d" 之后的字符,结果是:"\w+?" 只匹配了一个 "x"
     
    (d)(\w+?)(d)
     为了让整个表达式匹配成功,"\w+?" 不得不匹配 "xxx" 才可以让后边的 "d" 匹配,从而使整个表达式匹配成功。因此,结果是:"\w+?" 匹配 "xxx"
     
        
      

  9.   

    Mastering Regular Expressions 一书很经典