选择显示字体大小

正则表达式在网页处理中的应用四则(2)

     <%
  dim re, strhtml
  set re = new regexp ' 创建正则表达式对象
  
  re.ignorecase = true
  re.global = false ' 第一次匹配之后结束查找
  %>
  
    下面考虑一下我们要提取的区域:在这里,我们要提取的是整个<table>结构,包括结束标记和新闻标题的文本。因此查找的起始字符应该是<table>开始标记: re.pattern = "<table.*(?=headline)"。这个正则表达式匹配表格的开始标记,能够返回开始标记直至“headline”之间的所有内容(换行除外)。下面是返回已匹配html代码的方法:
  
  ' 把所有匹配的html代码放入matches集合
  set matches = re.execute(strhtml)
  
  ' 显示所有匹配的html代码
  for each item in matches
  response.write item.value
  next
  
  ' 显示其中一项
  response.write matches.item(0).value
  
    运行这段代码处理前面显示的html片断,正则表达式返回一次匹配的内容如下: <table border="0" width="11%" class="。正则表达式中的“(?=headline)”没有获取字符,所以不能看到表格class属性的值。要获取表格剩余部分的代码也相当简单: re.pattern = "<table.*(?=headline)(.\n)*?</table>"。其中:“(.\n)”后面的“*”匹配0个到多个任意字符;而“?”使得“*”匹配范围最小化,即在找到表达式的下一部分之前匹配尽可能少的字符。</table>是表格的结束标记。
  
    “?”限制符非常重要,它防止了表达式返回其他表格的代码。例如对于前面给出的html代码片断,如果删除这个“?”则返回内容将是:
  
  <table border="0" width="11%" class="headline">
  <tr>
  <td width="100%">
  <p align="center">伊拉克战争!</td>
  </tr>
  </table>
  <table border="0" width="11%" class="someotherstory">
  <tr>
  <td width="100%">
  <p align="center">其他内容...</td>
  </tr>
  </table>
  
  
    返回的内容不仅包含了headline表的<table>标记,而且还包含了someotherstory表格,由此可以看出,这里的“?”是必不可少的。
  
    本例假设了一些相当理想化的前提。实际应用中情况往往要复杂得多,特别是你对正在使用的源html代码的编写没有任何影响力时,编写asp代码尤为困难。最有效的方法是,多花些时间分析待提取内容附近的html,经常地测试,确保提取出来的内容正是自己所需要的。另外,应当重视并处理正则表达式不能匹配源html页面任何内容的情形。内容的更新可能非常快速,不要只因为别人改变了内容的格式而让自己的页面出现低级可笑的错误。
  
  
  三、解析文本数据文件
  
    数据文件的格式和种类很多,xml文档、结构化文本甚至非结构化文本都经常成为asp应用的数据源。下面我们要看的一个例子是使用限定符的结构化文本文件。限定符(比如引号)表示字符串各个部分不可分割,即使字符串内部包含把记录分隔成字段的分隔符也一样。
  
    下面是一个简单的结构化文本文件:
  
  姓,名, 电话, 说明
  孙,悟空, 312 555 5656, asp很好
  猪,八戒, 847 555 5656, 我是电影制片人
  
    这个文件非常简单,它的第一行是标题,下面两行是用逗号作为分隔符的记录。要解析这个文件也很简单,只需先把文件分割成行(根据换行符号),然后把各个记录按照字段分割。但是,如果我们在某个字段内容中加入了逗号:
  
  姓,名, 电话, 说明
  孙,悟空, 312 555 5656, 我喜欢asp,还有vb和sql
  猪,八戒, 847 555 5656, 我是电影制片人
  
    解析第一个记录时就会出现问题,因为在只认可逗号分隔符的解析器看来它的最后一个字段包含了两个字段的内容。为了避免出现这类问题,包含分隔符的字段必须用限定符包围。单引号就是一种常用的限定符。把上面的文本文件加上单引号限定符之后,它的内容如下所示:
  
  姓,名, 电话, 说明
  孙,悟空, 312 555 5656, '我喜欢asp,还有vb和sql'
  猪,八戒, 847 555 5656, '我是电影制片人'
  
    现在我们能够肯定哪一个逗号是分隔符、哪一个逗号是字段内容了,即只需把引号内部出现的逗号视为字段的内容。接下来我们要做的就是实现一个正则表达式解析器,由这个解析器确定何时根据逗号分割字段、何时把逗号视为字段内容。
  
    这里的问题与大多数正则表达式所面临的略有不同。通常我们查看的是文本的一小部分,看看它是否能够和正则表达式匹配。但在这里,只有考虑了整行文本之后我们才能可靠地判断出哪些内容位于引号之内。
  
    下面是一个说明该问题的例子。从某个文本文件随意抽取半行内容,得到:1, 沙滩, 黑色, 21, ', 狗, 猫, 鸭子, ', 。在这个例子中,因为“1”的左边还有其他数据,要解析清楚它的内容是极其困难的。我们不知道这个数据片断的前面有多少单引号,从而也就无法判断哪些字符位于引号之内(在引号之内的文本解析时不能分割)。如果这个数据片断之前有偶数个(或者没有)单引号,那么“', 狗, 猫, 鸭子, '”是用引号界定的字符串且不可分割。如果前面的引号数量是奇数,那么“1, 沙滩, 黑色, 21, '”是某个字符串的结束部分且不可分割。
  
    因此,正则表达式必须分析整行文本,全面考虑出现了多少引号才能确定字符是处在引号对的内部还是外部,即:,(?=([^']*'[^']*')*(?![^']*'))。这个正则表达式首先找到一个引号,然后继续查找并保证逗号后面的单引号数量或者是偶数、或者是0。该正则表达式以下面这个判断为基础:如果逗号后面的单引号数量是偶数,那么这个逗号位于字符串之外。下表给出了更详细的说明:
  
  , 寻找一个逗号
  (?= 继续向前查找以匹配下面这个模式
  ( 开始一个新的模式
  [^']*' [非引号字符]0个或者多个,然后是一个引号
  [^']*'[^']*) [非引号字符]0个或者多个,然后是一个引号。结合前面的内容之后它匹配引号对
  )* 结束模式并匹配整个模式(引号对)0次或者多次
  (?! 向前查找,排除此模式
  [^']*' [非引号字符]0个或者多个,然后是一个引号
  ) 结束模式
  
    下面是一个vbscript函数,它接受一个字符串参数,根据字符串中的逗号分隔符、单引号限定符分割字符串,返回结果数组:
  
  function splitadv(strinput)
  dim objre
  set objre = new regexp
  
  ' 设置regexp对象
  objre.ignorecase = true
  objre.global = true
  objre.pattern = ",(?=([^']*'[^']*')*(?![^']*'))"
  
  ' replace方法用chr(8)替换我们要用到的逗号,chr(8)即\b
  ' 字符,\b在字符串中出现的可能极为微小。
  ' 然后我们根据\b把字符串分割保存到数组
  splitadv = split(objre.replace(strinput, "\b"), "\b")
  end function
  
    总而言之,用正则表达式解析文本数据文件具有高效、缩短开发时间的优点,能够节省大量分析文件、根据复杂的条件提取有用数据的时间。在一个迅速发展的环境中仍会有许多传统的数据可资利用,掌握如何构造高效的数据分析例程将是一种宝贵的技能。
  
    四、字符串替换
  
    在最后一个例子中我们要看看vbscript正则表达式的替换功能。asp经常用于动态地格式化从各种数据源获得的文本。利用vbscript正则表达式的强大功能,asp能够动态地改变匹配的复杂文本。通过加入html标记突出显示部分单词就是一种常见的应用,比如突出显示搜索结果中的搜索关键词。
  
    为说明实现方法,下面我们来看一个突出显示字符串中所有“.net”的例子。这个字符串可以从任何地方获得,比如数据库或者其他web网站。
  
  <%
  set regex = new regexp
  regex.global = true
  regex.ignorecase = true
  
  ' 正则表达式模式
  ' 寻找任何结尾为“.net”的单词或者url。
  regex.pattern = "(\b[a-za-z\._]+?\.net\b)"
  
  ' 用于测试替换功能的字符串
  strtext = "微软建立了一个新网站www.asp.net。"
  
  ' 调用正则表达式的replace方法
  ' $1表示把匹配的文本插入当前位置
  response.write regex.replace(strtext, _
  "<b style='color: #000099; font-size: 18pt'>$1</b>")
  %>
  
    这个例子中有几个重要的地方必须注意。整个正则表达式被放入了一对圆括号中,它的作用是截取所有匹配的内容供以后使用,这些内容在替换文本中通过$1引用。类似的截取每次替换可以使用多达9个,分别通过$1到$9引用。正则表达式的replace方法和vbscript本身的replace函数不同,它只需要两个参数:被搜索的文本,替换用的文本。
  
    在这个例子中,为了突出显示搜索到的“.net”字符串,我们用粗体标记以及其他样式属性来包围这些字符串。使用这种搜索和替换技术,我们能够方便地为网站搜索程序加上突出显示搜索关键词的功能,或者自动为页面中出现的关键词加上指向其他页面的链接。
  
    结束语
  
    希望本文介绍的几种正则表达式技巧对你在何时、如何应用正则表达式有所启发。虽然本文的例子用vbscript编写,但在asp.net中正则表达式同样也大有用武之地,它是服务器端控件表单检验的主要机制之一,而且通过system.text.regularexpressions命名空间导出到了整个.net框架之中。
    


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons