网管联盟 | 网管论坛 | 网管u家 | 网管博客 | 网管软件 | 网管求职 | 小游戏 | 网管搜索 | 网管原创 | 网管聚合 | 网管读摘 | 网管焦点 | 世界素材 | 会员投稿 | 会员中心 
中国网管联盟
Windows Linux Cisco 网络技术 数据库 黑客攻防 DotNet Java PHP 认证 新闻资讯 服务器 存储资讯 网络设备 网管学堂 技术专题 焦点 网吧频道
 当前位置: > bitsCN.com > linux > Linux编程 > Perl编程 > 使用Perl常规表达式进行匹配  

使用Perl常规表达式进行匹配

2007-05-27  作者:bitsCN整理  来源:builder.com.cn  点评 投稿 收藏

长期以来,Perl以其对常规表达式的固有支持,一直是非常流行的文本处理工具。在这篇入门性文章中,我们将带领你简单了解如何在你自己的程序中使用常规表达式,实现更加强大的文本搜索和替代功能。

  我们首先了解最简单的常规表达式:匹配。如果在字符串中找到相匹配的模式,匹配操作就返回真值。因此下面的表达式: 中国网管联盟bitsCN.com

  $string =~ m/text/ 网管联盟bitsCN_com

  只有在变量“$string”中的字符串包含子字符串“text”时才返回真值。这是最基本的常规表达式,它对每个字符进行逐字匹配。当然,这只是对常规表达式作用的一个尝试。以需要查找以“ext”结尾的四个字母的单词为例。为达到这个目的,我们使用一个特殊的字符“.”,常规表达式中的句号告诉 Perl匹配其中的任何单独的字符。因此下面这个表达式:

中国网管联盟bitsCN.com

  $string =~ m/.ext/ 网管u家u.bitscn@com

  将与单词“text”和“next”匹配。

网管联盟bitsCN@com

  不过,这个表达式并非完美,因为它与包含“ext”的更长单词的一部分相匹配,如“dextrous”和“flextime”。我们可以使用锚字符来限制匹配的位置。“^”字符匹配字符串的开头,因此:

网管bitscn_com

  $string =~ m/^.ext/ 网管下载dl.bitscn.com

  与“dextrous”匹配,但不与“context”匹配。

中国网管联盟bitsCN.com

  同样,“$”字符匹配字符串的结尾: 网管bitscn_com

  $string =~ m/.ext$/ 网管u家u.bitsCN.com

  与“context”匹配,但不与“dextrous”匹配。

网管u家u.bitscn@com

  如果你只希望匹配以“ext”结尾的四个字母的字符串,那么你可以组合使用上面的两个表达式,像这样:

网管论坛bbs_bitsCN_com

  $string =~ m/^.ext$/

中国网管论坛bbs.bitsCN.com

  现在,如果你需要匹配一组给定的字符,而不是句号位置的任何字符,那该怎么办呢?常规表达式通过使用方括号提供一个方法。以下面的表达式为例:

网管联盟bitsCN@com

  $string =~ m/^[tT]ext$/ 网管论坛bbs_bitsCN_com

  这个表达式只与单词“text”和“Text”匹配。一对方括号将转换其中的任何单个字符。这个功能相当强大,例如:

网管联盟bitsCN@com

  $string =~ m/[aeiouAEIOU]/

网管联盟bitsCN@com

  如果$string变量中含有元音,则上面的例子返回真值。 网管u家u.bitscn@com

  如果括号中的第一个字符是“^”,这时它就不是一个锚字符,而是执行“非”操作,匹配不在括号内的任意字符,因此如果$string变量中只包含辅音或标点符号,可以对上面的例子进行调整,使它返回真值:

网管u家u.bitsCN.com

  $string =~ m/[^aeiouAEIOU]/

网管网www_bitscn_com

  方括号符号还可以指定字符的范围,让你不必列举一整串连续的数字或字母,例如,下面的例子匹配任何小写字母: 网管u家u.bitscn@com

  $string =~ m/[a-z]/ 网管网www.bitscn.com

到现在为止,我们每次都是处理字符串中的一个字符,但许多情况下我们需要处理更加复杂的问题。我们使用“|”或分段操作达到这个目的。假设我们希望检查$string变量中是否含有“next”或“previous”,我们可以使用下面的表达式:

网管论坛bbs_bitsCN_com

  $string =~ m/next|previous/

中国网管论坛bbs.bitsCN.com

  如果我们希望在这个表达式中使用锚字符,那么我们需要将选项组合起来,就像在算术中使用圆括号那样。因此,如果我们希望只匹配字符串开头部分的“next”或“previous”,可以这样写表达式: 中国网管联盟bitsCN.com

  $string =~ m/^(next|previous)/ 网管联盟bitsCN_com

  我们把所有这些操作符叫做原子操作符,就是说,它们与一个单独的字符相对应。不过,常规表达式的实际长度取决于操作的是循环次数。为说明这个问题,我们以确定一个字符串中是否包含一个有效电话号码为例。我们可以使用“glob”操作符,它写作“*”。许多以某种形式使用命令行的人都熟悉“*”用作通配符的情况,在Perl中它也有相似的用法,匹配任何数量的前一个字符构成的字符串。因此:

网管网www_bitscn_com

  $string =~ m/a*/

网管u家u.bitscn@com

  匹配由任意个a构成的字符串。现在我们匹配任意个数字:

网管u家u.bitscn@com

  $string =~ m/[0-9]*/

网管网www.bitscn.com

  这并不是我们所需要的表达式,因为它与任意数字,甚至是零相匹配。我们本可以用“+”代替“*”,它匹配一个或几个开始的那个字符,但这无法解决查找到的数字太长或太短的问题。我们真正需要的是指定循环的次数,在这个例子中为七次。这时我们可以使用大括号:

网管论坛bbs_bitsCN_com

  $string =~ m/^[0-9]$/ 网管联盟bitsCN_com

  这个结果更接近我们的目的,它匹配包含七个数字的字符串。大括号有另外一些选项,使它们在指定循环时功能更加强大,例如,你可以指定循环范围:

网管论坛bbs_bitsCN_com

  $string =~ m/[0-9]/ 网管u家u.bitscn@com

  这将匹配包含6个或8个数字的字符串,但如果我们用“”代替“”,就可以匹配6位或6位以上的字符串;而“”则匹配8位或8位以下的字符串。

网管u家u.bitsCN.com

  我们再看一下那些电话号码,现在它能够正常匹配,但仍然存在太多限制。不管什么时候,在处理用户输入时,你必须指望人们以各种方式进行简单操作。 中国网管联盟bitsCN.com

  尝试和预见一些更加常见的电话号码格式可能是个好主意。举一个简单的例子,如号码“2391720”,它能够以“239-1720”或“239 1720”的形式输入。现在我们可以使用圆括号来匹配“-”或“”,但我们需要新操作符来处理根本没有分隔符的情况:即“?”操作符,表示前面可以有也可以没有字符。我们可以用下面的表达式匹配所有这三种格式: 网管联盟bitsCN@com

  $string =~ m/[0-9][- ]?[0-9]/

网管bitscn_com

  同样,我们查看一下服务部门的号码。澳大利亚电话号码中有一个两位数的区号,我们在下面的表达式中增加它们: 网管u家u.bitscn@com

  $string =~ m/([0-9][- ]?)?[0-9][- ]?[0-9]/

中国网管论坛bbs.bitsCN.com

  这个表达式可以匹配“02 114 7682”这样的电话号码,而且,因为我们把区号部分放在圆括号中,使它成为可选内容,所以这个表达式还可以匹配前一个表达式匹配的格式。我们还可以做出更多改进,如把区号放在“(”和“)”中;但是,如你所见,你在表达式中增加越多选项,表达式就会越长越复杂,因此到底是否增加更多选项,由你自己决定。 网管下载dl.bitscn.com

  下次我们将深入讨论常规表达式的用法,包括替代、转换和如何建立你需要的Perl常规表达式程序。 网管论坛bbs_bitsCN_com


 上一篇:利用Perl读写MP3标记管理音乐文件   下一篇:没有了
使用Perl常规表达式进行匹配 评论:
loading.. 评论加载中…
评论:请自觉遵守互联网相关政策法规,评论不得超过250字。

验证码: 注册用户
本类热门排行:
最新推荐文章:
网管论坛交流: