http://bbs.hnedu.cn/read.bbs?bid=5&id=5015&page=2

解决方案 »

  1.   

    简单的说,正则表达式是一种可以用于模式匹配和替换的强有力的工具。我们可
    以在几乎所有的基于UNIX系统的工具中找到正则表达式的身影,例如,vi编辑器,Perl或
    PHP脚本语言,以及awk或sed 
          shell程序等。此外,象JavaScript这种客户端的脚本语言也提供了对正则表达式的
    支持。由此可见,正则表达式已经超出了某种语言或某个系统的局限,成为人们广为接受的
    概念和功能。         正则表达式可以让用户通过使用一系列的特殊字符构建匹配模式,然后把匹配模
    式与数据文件、程序输入以及WEB页面的表单输入等目标对象进行比较,根据比较对象中是
    否包含匹配模式,执行相应的程序。         举例来说,正则表达式的一个最为普遍的应用就是用于验证用户在线输入的邮件
    地址的格式是否正确。如果通过正则表达式验证用户邮件地址的格式正确,用户所填写的表
    单信息将会被正常处理;反之,如果用户输入的邮件地址与正则表达的模式不匹配,将会弹
    出提示信息,要求用户重新输入正确的邮件地址。由此可见正则表达式在WEB应用的逻辑判
    断中具有举足轻重的作用。       基本语法 
            在对正则表达式的功能和作用有了初步的了解之后,我们就来具体看一下正则表
    达式的语法格式。 
            正则表达式的形式一般如下: 
            /love/ 
            其中位于“/”定界符之间的部分就是将要在目标对象中进行匹配的模式。用户只
    要把希望查找匹配对象的模式内容放入“/”定界符之间即可。为了能够使用户更加灵活的定
    制模式内容,正则表达式提供了专门的“元字符”。所谓元字符就是指那些在正则表达式中具
    有特殊意义的专用字符,可以用来规定其前导字符(即位于元字符前面的字符)在目标对象
    中的出现模式。         较为常用的元字符包括: “+”, “*”,以及 
          “?”。其中,“+”元字符规定其前导字符必须在目标对象中连续出现一次或多次,“*”
    元字符规定其前导字符必须在目标对象中出现零次或连续多次,而“?”元字符规定其前导对
    象必须在目标对象中连续出现零次或一次。         下面,就让我们来看一下正则表达式元字符的具体应用。 
            /fo+/ 
            因为上述正则表达式中包含“+”元字符,表示可以与目标对象中的 “fool”, “fo”, 
    或者 
          “football”等在字母f后面连续出现一个或多个字母o的字符串相匹配。 
            /eg*/ 
            因为上述正则表达式中包含“*”元字符,表示可以与目标对象中的 “easy”, “ego”, 
    或者 
          “egg”等在字母e后面连续出现零个或多个字母g的字符串相匹配。 
            /Wil?/ 
            因为上述正则表达式中包含“?”元字符,表示可以与目标对象中的 “Win”, 或
    者 
          “Wilson”,等在字母i后面连续出现零个或一个字母l的字符串相匹配。 
            除了元字符之外,用户还可以精确指定模式在匹配对象中出现的频率。例如, 
            /jim/ 
            上述正则表达式规定字符m可以在匹配对象中连续出现2-6次,因此,上述正则
    表达式可以同jimmy或jimmmmmy等字符串相匹配。 
            在对如何使用正则表达式有了初步了解之后,我们来看一下其它几个重要的元字
    符的使用方式。 
            \s:用于匹配单个空格符,包括tab键和换行符; 
            \S:用于匹配除单个空格符之外的所有字符; 
            \d:用于匹配从0到9的数字; 
            \w:用于匹配字母,数字或下划线字符; 
            \W:用于匹配所有与\w不匹配的字符; 
            . :用于匹配除换行符之外的所有字符。 
            (说明:我们可以把\s和\S以及\w和\W看作互为逆运算) 
            下面,我们就通过实例看一下如何在正则表达式中使用上述元字符。 
            /\s+/ 
            上述正则表达式可以用于匹配目标对象中的一个或多个空格字符。 
            /\d000/ 
            如果我们手中有一份复杂的财务报表,那么我们可以通过上述正则表达式轻而易
    举的查找到所有总额达千元的款项。 
            除了我们以上所介绍的元字符之外,正则表达式中还具有另外一种较为独特的专
    用字符,即定位符。定位符用于规定匹配模式在目标对象中的出现位置。 
            较为常用的定位符包括: “^”, “$”, “\b” 以及 
          “\B”。其中,“^”定位符规定匹配模式必须出现在目标字符串的开头,“$”定位符规
    定匹配模式必须出现在目标对象的结尾,\b定位符规定匹配模式必须出现在目标字符串的开
    头或结尾的两个边界之一,而“\B”定位符则规定匹配对象必须位于目标字符串的开头和结
    尾两个边界之内,即匹配对象既不能作为目标字符串的开头,也不能作为目标字符串的结尾。
    同样,我们也可以把“^”和“$”以及“\b”和“\B”看作是互为逆运算的两组定位符。举
    例来说:         /^hell/ 
            因为上述正则表达式中包含“^”定位符,所以可以与目标对象中以 “hell”, 
    “hello”或 “hellhound”开头的字符串相匹配。 
            /ar$/ 
            因为上述正则表达式中包含“$”定位符,所以可以与目标对象中以 “car”, “bar”
    或 “ar” 结尾的字符串相匹配。 
            /\bbom/ 
            因为上述正则表达式模式以“\b”定位符开头,所以可以与目标对象中以 “bomb”, 
    或 “bom”开头的字符串相匹配。 
            /man\b/ 
            因为上述正则表达式模式以“\b”定位符结尾,所以可以与目标对象中以 “human”, 
    “woman”或 “man”结尾的字符串相匹配。 
            为了能够方便用户更加灵活的设定匹配模式,正则表达式允许使用者在匹配模式
    中指定某一个范围而不局限于具体的字符。例如: 
            /[A-Z]/ 
            上述正则表达式将会与从A到Z范围内任何一个大写字母相匹配。 
            /[a-z]/ 
            上述正则表达式将会与从a到z范围内任何一个小写字母相匹配。 
            /[0-9]/ 
            上述正则表达式将会与从0到9范围内任何一个数字相匹配。 
            /([a-z][A-Z][0-9])+/ 
            上述正则表达式将会与任何由字母和数字组成的字符串,如 “aB0” 等相匹配。
    这里需要提醒用户注意的一点就是可以在正则表达式中使用 “()” 
          把字符串组合在一起。“()”符号包含的内容必须同时出现在目标对象中。因此,上述
    正则表达式将无法与诸如 
          “abc”等的字符串匹配,因为“abc”中的最后一个字符为字母而非数字。 
            如果我们希望在正则表达式中实现类似编程逻辑中的“或”运算,在多个不同的
    模式中任选一个进行匹配的话,可以使用管道符 “|”。例如: 
            /to|too|2/ 
            上述正则表达式将会与目标对象中的 “to”, “too”, 或 “2” 相匹配。 
            正则表达式中还有一个较为常用的运算符,即否定符 “[^]”。与我们前文所介绍
    的定位符 “^” 不同,否定符 
          “[^]”规定目标对象中不能存在模式中所规定的字符串。例如: 
            /[^A-C]/ 
            上述字符串将会与目标对象中除A,B,和C之外的任何字符相匹配。一般来说,
    当“^”出现在 
          “[]”内时就被视做否定运算符;而当“^”位于“[]”之外,或没有“[]”时,则应
    当被视做定位符。 
            最后,当用户需要在正则表达式的模式中加入元字符,并查找其匹配对象时,可
    以使用转义符“\”。例如: 
            /Th\*/ 
            上述正则表达式将会与目标对象中的“Th*”而非“The”等相匹配。 
          使用实例 
      

  2.   

    在对正则表达式有了较为全面的了解之后,我们就来看一下如何在Perl,PHP,
    以及JavaScript中使用正则表达式。 
            通常,Perl中正则表达式的使用格式如下: 
            operator / regular-expression / string-to-replace / modifiers 
            运算符一项可以是m或s,分别代表匹配运算和替换运算。 
            其中,正则表达式一项是将要进行匹配或替换操作的模式,可以由任意字符,元
    字符,或定位符等组成。替换字符串一项是使用s运算符时,对查找到的模式匹配对象进行
    替换的字符串。最后的参数项用来控制不同的匹配或替换方式。例如:         s/geed/good/ 
            将会在目标对象中查找第一个出现的geed字串,并将其替换为good。如果我们
    希望在目标对象的全局范围内执行多次查找—替换操作的话,可以使用参数 
          “g”,即s/love/lust/g。 
            此外,如果我们不需要限制匹配的大小写形式的话,可以使用参数 “i ”。例如, 
            m/JewEL/i 
            上述正则表达式将会与目标对象中的jewel,Jewel,或JEWEL相匹配。 
            在Perl中,使用专门的运算符“=~”指定正则表达式的匹配对象。例如: 
            $flag =~ s/abc/ABC/ 
            上述正则表达式将会把变量$flag中的字串abc替换为ABC。 
            下面,我们就在Perl程序中加入正则表达式,验证用户邮件地址格式的有效性。
    代码如下: 
          -------------------------------------------------------- 
            #!/usr/bin/perl 
            # get input 
            print “What's your email address?\n”; 
            $email = <STDIN> 
            chomp($email); 
            # match and display result 
            if($email =~ /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/) 
            { 
            print(“Your email address is correct!\n”); 
            } 
            else 
             { 
              print(“Please try again!\n”); 
             } 
          -------------------------------------------------------- 
            如果用户更偏爱PHP的话,可以使用ereg()函数进行模式匹配操作。ereg()函数
    的使用格式如下: 
             ereg(pattern, string) 
            其中,pattern代表正则表达式的模式,而string则是执行查找替换操作的目标
    对象。同样是验证邮件地址,使用PHP编写的程序代码如下: 
          -------------------------------------------------------- 
            <?php 
             if 
          (ereg(“^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+”,$email)) 
              { echo “Your email address is correct!”;} 
             else 
              { echo “Please try again!”;} 
             ?> 
          -------------------------------------------------------- 
            最后,我们在来看一下JavaScript。JavaScript 
          1.2中带有一个功能强大的RegExp()对象,可以用来进行正则表达式的匹配操作。其
    中的test()方法可以检验目标对象中是否包含匹配模式,并相应的返回true或false。         我们可以使用JavaScript编写以下脚本,验证用户输入的邮件地址的有效性。 
          -------------------------------------------------------- 
            <html> 
             <head> 
              <script language="Javascript1.2"> 
               <!-- start hiding 
               function verifyAddress(obj) 
               { 
                var email = obj.email.value; 
                var pattern = 
          /^([a-zA-Z0-9_-])+@([a-zA-Z0-9_-])+(\.[a-zA-Z0-9_-])+/; 
                flag = pattern.test(email); 
                if(flag) 
                { 
                 alert(“Your email address is correct!”); 
                 return true; 
                } 
                else 
                 { 
                  alert(“Please try again!”); 
                  return false; 
                  } 
                } 
               // stop hiding --> 
              </script> 
             </head> 
             <body>          <input name="email" type="text" id="email" onBlur="verifyAddress(this)"> 
             
            </body> 
           </html> 
          -------------------------------------------------------- 
          Perl的经典用法:用正则表达式对文件进行操作 
          本文出自:www.zdnet.com.cn 作者:Nathan Torkington (2001-12-29 13:02:04) 
          一旦你有个包含了整个串的变量,你可以使用正则表达式,对整个文件进行操作, 
          而不是对文件中的某个块进行操作。有两个有用的正则表达式标记/s和/m。一般,Perl
    的 正则表达式对行进行处理,你可以这样写:
          undef $/;
          $line = ;
          if ($line =~ /(b.*grass)$/) {
          print "found $1\n";
          }      如果把我们的文件填入如下内容: browngrass
          bluegrass
          则输出为:
          found bluegrass
          它没有找到“browngrass”,这是因为$ 仅在串尾寻找其匹配, (或者在串结束 前的
    一行)。如果在包含很多行的串中,用"^" 
          和"$"来匹配,, 我们可以使用 /m ("multiline") 选项:
          if ($line =~ /(b.*grass)$/m) {}
          现在程序会把如下的信息输出:
          found browngrass
          类似地,句点可以匹配除了换行符之外的所有字符:
          while () {
          if (/19(.*)$/) {
          if ($1 < 20) {
          $year = 2000+$1;
          } else {
          $year = 1900+$1;
          }
          }
          }      如果我们从文件中读入“1981”,$_ 将包含“1981\n”。正则表达式中的句点 匹配“8”
    和“1”, 
          而不匹配“\n”。这里正需要这样做,因为换行符不是日期的组成部分。
          对于一个包含很多行的串,我们也许要提取其中的大的块,这些块可能会跨越行分隔
    符。 在这种情况下,我们可以使用 /s 
          选项,并用句点来匹配除了换行符以外的所有字符。
          if (m{(.*?)}s) {
          print "Found bold text: $1\n";
          }      此处,我用了{}来表示正则表达式的起始和结束,而不用斜杠,所以,我就可以 告诉 
    Perl我正在匹配,起始字符为"m",结束字符为"s"。你 
          可以把/s 和/m 选项组合使用:
          if (m{^(.*?)}sm) {
          # ...
          }      总结
          有两种方法打开文件:open()函数的特点是快速简捷,而sysopen()函数功能强 大而
    复杂。通过 操作符,可以读入一个记录,$/ 
          变量可以让你控制记 录是什么。如果你打算把很多行的内容读入到一个串中,不要使
    用忘记/s和/m 这两 个正则表达式标记。