Board logo

标题: 正则表达式系统教程 [打印本页]

作者: chinanic    时间: 2006-11-25 17:44     标题: 正则表达式系统教程

  一、正则表达式概述   二、正则表达式在VBScript中的应用   三、正则表达式在VavaScript中的应用   四、示例   五、总结   一、正则表达式概述   如果原来没有使用过正则表达式,那么可能对这个术语和概念会不太熟悉。不过,它们并不是您想象的那么新奇。   请回想一下在硬盘上是如何查找文件的。您肯定会使用 ? 和 * 字符来帮助查找您正寻找的文件。? 字符匹配文件名中的单个字符,而 * 则匹配一个或多个字符。一个如 ';data?.dat'; 的模式可以找到下述文件:data1.dat、data2.dat等等。如果使用 * 字符代替 ? 字符,则将扩大找到的文件数量。';data*.dat'; 可以匹配下述所有文件名:data.dat、data1.dat、data12.dat等等,尽管这种搜索文件的方法肯定很有用,但也十分有限。? 和 * 通配符的有限能力可以使你对正则表达式能做什么有一个概念,不过正则表达式的功能更强大,也更灵活。   在我们编写ASP程序时,经常会判断一个字符串的有效性,如;一个串是否是数字、是否是有效的Email地址等等。如果不使用正则表达式,那么判断的程序会很长,并且容易出错,如果使用正则表达式,这些判断就是一件很轻松的工作了。后面我们将介绍如何判断数字和Email地址的有效性。   在典型的搜索和替换操作中,必须提供要查找的确切文字。这种技术对于静态文本中的简单搜索和替换任务可能足够了,但是由于它缺乏灵活性,因此在搜索动态文本时就有困难了,甚至是不可能的。   使用正则表达式,能完成些什么事情呢?   测试字符串的某个模式。例如,可以对一个输入字符串进行测试,看在该字符串是否存在一个电话号码模式或一个信用卡号码模式。这称为数据有效性验证。   替换文本。可以在文档中使用一个正则表达式来标识特定文字,然后可以全部将其删除,或者替换为别的文字。   根据模式匹配从字符串中提取一个子字符串。可以用来在文本或输入字段中查找特定文字。   例如,如果需要搜索整个 web 站点来删除某些过时的材料并替换某些HTML 格式化标记,则可以使用正则表达式对每个文件进行测试,看在该文件中是否存在所要查找的材料或 HTML 格式化标记。用这个方法,就可以将受影响的文件范围缩小到包含要删除或更改的材料的那些文件。然后可以使用正则表达式来删除过时的材料,最后,可以再次使用正则表达式来查找并替换那些需要替换的标记。   那么,正则表达式语法的语法是如何呢?   一个正则表达式就是由普通字符(例如字符 a 到 z)以及特殊字符(称为元字符)组成的文字模式。该模式描述在查找文字主体时待匹配的一个或多个字符串。正则表达式作为一个模板,将某个字符模式与所搜索的字符串进行匹配。   这里有一些可能会遇到的正则表达式示例:   /^[ t]*$/ "^[ t]*$" 匹配一个空白行。   /d{2}-d{5}/ "d{2}-d{5}" 验证一个ID 号码是否由一个2位数字,一个连字符以及一个5位数字组成。   /<(.*)>.*/ "<(.*)>.*" 匹配一个 HTML 标记。   二、正则表达式在VBScript中的应用   VBScript使用RegExp对象、Matches集合以及Match对象提供正则表达式支持功能。我们还是先看一个例子。 <% Function RegExpTest(patrn, strng) Dim regEx, Match, Matches   ';建立变量。 Set regEx = New RegExp   ';建立正则表达式。 regEx.Pattern = patrn  ';设置模式。 regEx.IgnoreCase = True   ';设置是否区分字符大小写。 regEx.Global = True   ';设置全局可用性。 Set Matches = regEx.Execute(strng)  ';执行搜索。 For Each Match in Matches  ';遍历匹配集合。 RetStr = RetStr & "Match found at position " RetStr = RetStr & Match.FirstIndex & ". Match Value is ';" RetStr = RetStr & Match.Value & "';." & "
" Next RegExpTest = RetStr End Function response.write RegExpTest("[ij]s.", "IS1 Js2 IS3 is4") %> 在这个例子中,我们查找字符串中有无is或者js这两个词,忽略大小写。运行的结果如下: Match found at position 0. Match Value is ';IS1';. Match found at position 4. Match Value is ';Js2';. Match found at position 8. Match Value is ';IS3';. Match found at position 12. Match Value is ';is4';. 下面我们就介绍这三个对象和集合。   1、RegExp对象是最重要的一个对象,它有几个属性,其中:   ○Global 属性,设置或返回一个 Boolean 值,该值指明在整个搜索字符串时模式是全部匹配还是只匹配第一个。如果搜索应用于整个字符串,Global 属性的值为 True,否则其值为 False。默认的设置为 False。   ○IgnoreCase 属性,设置或返回一个Boolean值,指明模式搜索是否区分大小写。如果搜索是区分大小写的,则 IgnoreCase 属性为 False;否则为 True。缺省值为 False。   ○Pattern 属性,设置或返回被搜索的正则表达式模式。必选项。总是一个 RegExp 对象变量。   2、Match 对象   匹配搜索的结果是存放在Match对象中,提供了对正则表达式匹配的只读属性的访问。 Match 对象只能通过 RegExp 对象的 Execute 方法来创建,该方法实际上返回了 Match 对象的集合。所有的 Match 对象属性都是只读的。在执行正则表达式时,可能产生零个或多个 Match 对象。每个 Match 对象提供了被正则表达式搜索找到的字符串的访问、字符串的长度,以及找到匹配的索引位置等。   ○FirstIndex 属性,返回在搜索字符串中匹配的位置。FirstIndex 属性使用从零起算的偏移量,该偏移量是相对于搜索字符串的起始位置而言的。换言之,字符串中的第一个字符被标识为字符 0   ○Length 属性,返回在字符串搜索中找到的匹配的长度。   ○Value 属性,返回在一个搜索字符串中找到的匹配的值或文本。   3、Matches 集合   正则表达式 Match 对象的集合。Matches 集合中包含若干独立的 Match 对象,只能使用 RegExp 对象的 Execute 方法来创建之。与独立的 Match 对象属性相同,Matches `集合的一个属性是只读的。在执行正则表达式时,可能产生零个或多个 Match 对象。每个 Match 对象都提供了与正则表达式匹配的字符串的访问入口、字符串的长度,以及标识匹配位置的索引。   学习了这三个对象和集合,如何应用于字符串的判断和替换呢?regExp对象的三个方法正好解决了这个问题,它们是Replace方法、Test方法和Execute方法。   1、Replace 方法   替换在正则表达式查找中找到的文本。我们还是先看个例子:下面的例子说明了 Replace 方法的用法。 <% Function ReplaceTest(patrn, replStr) Dim regEx, str1 '; 建立变量。 str1 = "The quick brown fox jumped over the lazy dog." Set regEx = New RegExp '; 建立正则表达式。 regEx.Pattern = patrn '; 设置模式。 regEx.IgnoreCase = True '; 设置是否区分大小写。 ReplaceTest = regEx.Replace(str1, replStr) '; 作替换。 End Function Response.write ReplaceTest("fox", "cat") & "
" '; 将 ';fox'; 替换为 ';cat';。 Response.write ReplaceTest("(S+)(s+)(S+)", "$3$2$1") '; 交换词对. %>   2、Test 方法   对指定的字符串执行一个正则表达式搜索,并返回一个 Boolean 值指示是否找到匹配的模式。正则表达式搜索的实际模式是通过RegExp对象的Pattern属性来设置的。RegExp.Global属性对Test方法没有影响。   如果找到了匹配的模式,Test方法返回True;否则返回False。下面的代码说明了Test 方法的用法。 <% Function RegExpTest(patrn, strng) Dim regEx, retVal '; 建立变量。 Set regEx = New RegExp '; 建立正则表达式。 regEx.Pattern = patrn '; 设置模式。 regEx.IgnoreCase = False '; 设置是否区分大小写。 retVal = regEx.Test(strng) '; 执行搜索测试。 If retVal Then RegExpTest = "找到一个或多个匹配。" Else RegExpTest = "未找到匹配。" End If End Function Response.write RegExpTest("is.", "IS1 is2 IS3 is4") %>   3、Execute 方法   对指定的字符串执行正则表达式搜索。正则表达式搜索的设计模式是通过 RegExp 对象的 Pattern 来设置的。   Execute 方法返回一个 Matches 集合,其中包含了在 string 中找到的每一个匹配的 Match 对象。如果未找到匹配,Execute 将返回空的 Matches 集合。   三、JavaScript中正则表达式的使用   在JavaScript 1.2版以后,JavaScript也支持正则表达式。   1、replace   replace在一个字符串中通过正则表达式查找替换相应的内容。replace并不改变原来的字符串,只是重新生成了一个新的字符串。如果需要执行全局查找或忽略大小写,那么在正则表达式的最后添加g和i。 例: 结果是:"oranges are round, and oranges are juicy." 例: 结果是:"Twas the night before Christmas..." 例: 结果是:"Smith, John".   2、search search通过正则表达式查找相应的字符串,只是判断有无匹配的字符串。如果查找成功,search返回匹配串的位置,否则返回-1。          search(regexp)   3、match   match方法执行全局查找,查找结果存放在一个数组里。 例一: 显示结果:Chapter 3.4.5.1,Chapter 3.4.5.1,.1 例二: 显示结果D, d.   四、示例 1 、判断数字的正确性 <%@ Language=VBScript %> 判断数字的正确性 <% Dim strTemp strTemp = CStr(Request.Form("inputstring")) If strTemp = "" Then strTemp = "0" %>
原始字符串 <%= strTemp %>
数字 <%=isNumeric(strTemp)%>
非负数字 <%=isUnsignedNumeric(strTemp)%>
整数 <%=isInteger(strTemp)%>
非负整数() <%=isUnsignedInteger(strTemp)%>
" METHOD="post"> 请输入一个数字:


2、判断Email地址的正确性 <% Function isemail(strng) isemail = false Dim regEx, Match Set regEx = New RegExp regEx.Pattern = "^w+((-w+)|(.w+))*@[A-Za-z0-9]+((.|-)[A-Za-z0-9]+)*.[A-Za-z0-9]+$" regEx.IgnoreCase = True Set Match = regEx.Execute(strng) if match.count then isemail= true End Function %>  五、总结   上面我们介绍了正则表达式的基本概念,以及在VBScript和JavaScript中如何使用正则表达式,同时,通过一些实例让大家有了感性的认识。正则表达式的应用范围很广,能为大家解决很多实际中的问题。本文介绍的内容只是一些初步的知识,还有很多语法规则需要大家继续学习,在实践中发现问题,解决问题。 返回顶部              怎么实现数据记录的分页显示(作者:DarkMan) 怎么实现数据记录的分页显示 (1) 通过Recordset的GetRows方法,可以实现数据记录的分页显示。下面是一个完整的例子: <%@ Language = VBSCRIPT %> <% Option Explicit %> <% Dim iStart, iOffset iStart = Request("Start") iOffset = Request("Offset") if Not IsNumeric(iStart) or Len(iStart) = 0 then   iStart = 0 else   iStart = CInt(iStart) end if if Not IsNumeric(iOffset) or Len(iOffset) = 0 then   iOffset = 10 else   iOffset = Cint(iOffset) end if Response.Write "察看 " & iOffset & " 个记录从 " & iStart & "开始
" Dim objConn, objRS Set objConn = Server.CreateObject("ADODB.Connection") objConn.Open "Provider=SQLOLEDB.1;Data Source=(local);uid=sa;pwd=;Initial    Catalog=pubs" Set objRS = Server.CreateObject("ADODB.Recordset") objRS.Open "SELECT * FROM Authors", objConn Dim aResults aResults = objRS.GetRows objRS.Close Set objRS = Nothing objConn.Close Set objConn = Nothing Dim iRows, iCols, iRowLoop, iColLoop, iStop iRows = UBound(aResults, 2) iCols = UBound(aResults, 1) If iRows > (iOffset + iStart) Then   iStop = iOffset + iStart - 1 Else   iStop = iRows End If For iRowLoop = iStart to iStop   For iColLoop = 0 to iCols  Response.Write aResults(iColLoop, iRowLoop) & " "  Next   Response.Write "
"  Next Response.Write "

" if iStart > 0 then ';显示“前 10个”连接   Response.Write "前 " & iOffset & ""  end if if iStop < iRows then ';显示“后 10个”连接  Response.Write " 后 " & iOffset & "" end if %> 怎么实现数据的分页显示(2) 这里介绍另外一种分页显示的方法,是通过 MS SQL的存储过程。本方法不适用于Access数据库。 假设我们要对数据表MyTable的数据实现分页显示,首先写一个存储过程 如下: CREATE PROCEDURE sp_PagedItems  (   @Page int,   @RecsPerPage int   )   AS   -- 加快表的 插入速度   SET NOCOUNT ON   -- 开始记录 号   DECLARE @RecCount int   SELECT @RecCount = @RecsPerPage * @Page + 1   --创建临时 表   CREATE TABLE #TempItems   (   ID int IDENTITY,   Name varchar(50),   Price currency  )   -- 准备临时 表   INSERT INTO #TempItems (Name, Price)   SELECT Name,Price FROM MyTable ORDER BY Price   -- 求出要查 询的最小ID和最大ID   DECLARE @FirstRec int, @LastRec int   SELECT @FirstRec = (@Page - 1) * @RecsPerPage   SELECT @LastRec = (@Page * @RecsPerPage + 1)   -- 得到实际 的记录,并返回是否还有数据!   SELECT *,   MoreRecords =  (   SELECT COUNT(*)   FROM #TempItems TI   WHERE TI.ID >= @LastRec  )   FROM #TempItems   WHERE ID > @FirstRec AND ID < @LastRec   -- 恢复设置   SET NOCOUNT OFF   在这个存储过程里,我们首先创建一个全部 记录的临时表,并增加了一个自动编号的字段ID。这样,不同的记录就有一个递增的唯一标志。   根据当前的页号和每页的记录数,可以计算 出每页的最小和最大的ID。从而得到当前页的所有记录。   为了显示的方便,存储过程还计算了 MoreRecords字段,作为显示下一页的判断条件。   利用了这个存储过程的程序代码如下:  <%   ';每页显示10条   Const iRecordsPerPage = 10   Dim currentPage ';当前页号   Dim bolLastPage ';在最后一页?     if len(Request.QueryString("page")) = 0 then    currentPage = 1  else    currentPage = CInt(Request.QueryString("page"))  end if   ';得到当前页的记录   strSQL = "sp_PagedItems " & currentPage & "," & iRecordsPerPage   objRS.Open strSQL, objConn      ';判断是否在最后一页  if Not objRS.EOF then    if CInt(objRS("MoreRecords")) > 0 then     bolLastPage = False    else     bolLastPage = True    end if   end if   %>   

      <%   Do While Not objRS.EOF %>      <% objRS.MoveNext   Loop %>  
       List of Items      
   <%=objRS("Name")%>       <%=FormatCurrency(objRS("Price"))%>   
  

  

 <%   ';第一页不 显示“前一页”  if currentPage > 1 then %>    ;     <% end if   ';最后一页 不显示“后一页”  if Not bolLastPage then %>    ;  <% end if %>   
   "^\d+$"  //非负整数(正整数 + 0) "^[0-9]*[1-9][0-9]*$"  //正整数 "^((-\d+)|(0+))$"  //非正整数(负整数 + 0) "^-[0-9]*[1-9][0-9]*$"  //负整数 "^-?\d+$"    //整数 "^\d+(\.\d+)?$"  //非负浮点数(正浮点数 + 0) "^(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*))$"  //正浮点数 "^((-\d+(\.\d+)?)|(0+(\.0+)?))$"  //非正浮点数(负浮点数 + 0) "^(-(([0-9]+\.[0-9]*[1-9][0-9]*)|([0-9]*[1-9][0-9]*\.[0-9]+)|([0-9]*[1-9][0-9]*)))$"  //负浮点数 "^(-?\d+)(\.\d+)?$"  //浮点数 "^[A-Za-z]+$"  //由26个英文字母组成的字符串 "^[A-Z]+$"  //由26个英文字母的大写组成的字符串 "^[a-z]+$"  //由26个英文字母的小写组成的字符串 "^[A-Za-z0-9]+$"  //由数字和26个英文字母组成的字符串 "^\w+$"  //由数字、26个英文字母或者下划线组成的字符串 "^[\w-]+(\.[\w-]+)*@[\w-]+(\.[\w-]+)+$"    //email地址 "^[a-zA-z]+://(\w+(-\w+)*)(\.(\w+(-\w+)*))*(\?\S*)?$"  //url




欢迎光临 黑色海岸线论坛 (http://bbs.thysea.com/) Powered by Discuz! 7.2