首页 »Linux » perl正则表达式:使用Perl常规表达式进行匹配 »正文
perl正则表达式:使用Perl常规表达式进行匹配
来源: 发布时间:星期四, 2009年2月12日 浏览:30次 评论:0
长期以来 ![](/icons/98766dou.gif) Perl以其对常规表达式 ![](/icons/98766de.gif) 固有支持 ![](/icons/98766dou.gif) ![](/icons/98766yi.gif) 直是非常流行 ![](/icons/98766de.gif) 文本处理工具 ![](/icons/98766dou2.gif) 在这篇入门性文章中 ![](/icons/98766dou.gif) 我们将带领你简单了解如何在你自己 ![](/icons/98766de.gif) ![](/icons/98766chengxu.gif) 中使用常规表达式 ![](/icons/98766dou.gif) 实现更加强大 ![](/icons/98766de.gif) 文本搜索和替代功能 ![](/icons/98766dou2.gif)
我们首先了解最简单 ![](/icons/98766de.gif) 常规表达式:匹配 ![](/icons/98766dou2.gif) 如果在 ![](/icons/98766zifu.gif) 串中找到相匹配 ![](/icons/98766de.gif) 模式 ![](/icons/98766dou.gif) 匹配操作就返回真值 ![](/icons/98766dou2.gif) 因此下面 ![](/icons/98766de.gif) 表达式:
$ ![](/icons/98766string.gif) =~ m/text/
只有在变量“$ ![](/icons/98766string.gif) ”中 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串包含子 ![](/icons/98766zifu.gif) 串“text”时才返回真值 ![](/icons/98766dou2.gif) 这是最基本 ![](/icons/98766de.gif) 常规表达式 ![](/icons/98766dou.gif) 它对每个 ![](/icons/98766zifu.gif) 进行逐字匹配 ![](/icons/98766dou2.gif) 当然 ![](/icons/98766dou.gif) 这只是对常规表达式作用 ![](/icons/98766de.gif) ![](/icons/98766yi.gif) 个尝试 ![](/icons/98766dou2.gif) 以需要查找以“ext”结尾 ![](/icons/98766de.gif) 4个字母 ![](/icons/98766de.gif) 单词为例 ![](/icons/98766dou2.gif) 为达到这个目 ![](/icons/98766de.gif) ![](/icons/98766dou.gif) 我们使用 ![](/icons/98766yi.gif) 个特殊 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) “.” ![](/icons/98766dou.gif) 常规表达式中 ![](/icons/98766de.gif) 句号告诉 Perl匹配其中 ![](/icons/98766de.gif) 任何单独 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) ![](/icons/98766dou2.gif) 因此下面这个表达式:
$ ![](/icons/98766string.gif) =~ m/.ext/
将和单词“text”和“next”匹配 ![](/icons/98766dou2.gif)
不过 ![](/icons/98766dou.gif) 这个表达式并非完美 ![](/icons/98766dou.gif) ![](/icons/98766yinwei.gif) 它和包含“ext” ![](/icons/98766de.gif) 更长单词 ![](/icons/98766de.gif) ![](/icons/98766yi.gif) 部分相匹配 ![](/icons/98766dou.gif) 如“dextrous”和“flextime” ![](/icons/98766dou2.gif) 我们可以使用锚 ![](/icons/98766zifu.gif) 来限制匹配 ![](/icons/98766de.gif) 位置 ![](/icons/98766dou2.gif) “^” ![](/icons/98766zifu.gif) 匹配 ![](/icons/98766zifu.gif) 串 ![](/icons/98766de.gif) 开头 ![](/icons/98766dou.gif) 因此:
$ ![](/icons/98766string.gif) =~ m/^.ext/
和“dextrous”匹配 ![](/icons/98766dou.gif) 但不和“context”匹配 ![](/icons/98766dou2.gif)
同样 ![](/icons/98766dou.gif) “$” ![](/icons/98766zifu.gif) 匹配 ![](/icons/98766zifu.gif) 串 ![](/icons/98766de.gif) 结尾:
$ ![](/icons/98766string.gif) =~ m/.ext$/
和“context”匹配 ![](/icons/98766dou.gif) 但不和“dextrous”匹配 ![](/icons/98766dou2.gif)
如果你只希望匹配以“ext”结尾 ![](/icons/98766de.gif) 4个字母 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou.gif) 那么你可以组合使用上面 ![](/icons/98766de.gif) 两个表达式 ![](/icons/98766dou.gif) 像这样:
$ ![](/icons/98766string.gif) =~ m/^.ext$/
现在 ![](/icons/98766dou.gif) 如果你需要匹配 ![](/icons/98766yi.gif) 组给定 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 而不是句号位置 ![](/icons/98766de.gif) 任何 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 那该如何办呢?常规表达式通过使用方括号提供 ![](/icons/98766yi.gif) 个思路方法 ![](/icons/98766dou2.gif) 以下面 ![](/icons/98766de.gif) 表达式为例:
$ ![](/icons/98766string.gif) =~ m/^[tT]ext$/
这个表达式只和单词“text”和“Text”匹配 ![](/icons/98766dou2.gif) ![](/icons/98766yi.gif) 对方括号将转换其中 ![](/icons/98766de.gif) 任何单个 ![](/icons/98766zifu.gif) ![](/icons/98766dou2.gif) 这个功能相当强大 ![](/icons/98766dou.gif) 例如:
$ ![](/icons/98766string.gif) =~ m/[aeiouAEIOU]/
如果$ ![](/icons/98766string.gif) 变量中含有元音 ![](/icons/98766dou.gif) 则上面 ![](/icons/98766de.gif) 例子返回真值 ![](/icons/98766dou2.gif)
如果括号中 ![](/icons/98766de.gif) 第 ![](/icons/98766yi.gif) 个 ![](/icons/98766zifu.gif) 是“^” ![](/icons/98766dou.gif) 这时它就不是 ![](/icons/98766yi.gif) 个锚 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 而是执行“非”操作 ![](/icons/98766dou.gif) 匹配不在括号内 ![](/icons/98766de.gif) 任意 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 因此如果$ ![](/icons/98766string.gif) 变量中只包含辅音或标点符号 ![](/icons/98766dou.gif) 可以对上面 ![](/icons/98766de.gif) 例子进行调整 ![](/icons/98766dou.gif) 使它返回真值:
$ ![](/icons/98766string.gif) =~ m/[^aeiouAEIOU]/
方括号符号还可以指定 ![](/icons/98766zifu.gif) ![](/icons/98766de.gif) 范围 ![](/icons/98766dou.gif) 让你不必列举 ![](/icons/98766yi.gif) 整串连续 ![](/icons/98766de.gif) 数字或字母 ![](/icons/98766dou.gif) 例如 ![](/icons/98766dou.gif) 下面 ![](/icons/98766de.gif) 例子匹配任何小写字母:
$ ![](/icons/98766string.gif) =~ m/[a-z]/
到现在为止 ![](/icons/98766dou.gif) 我们每次都是处理 ![](/icons/98766zifu.gif) 串中 ![](/icons/98766de.gif) ![](/icons/98766yi.gif) 个 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 但许多情况下我们需要处理更加复杂 ![](/icons/98766de.gif) 问题 ![](/icons/98766dou2.gif) 我们使用“|”或分段操作达到这个目 ![](/icons/98766de.gif) ![](/icons/98766dou2.gif) 假设我们希望检查$ ![](/icons/98766string.gif) 变量中是否含有“next”或“previous” ![](/icons/98766dou.gif) 我们可以使用下面 ![](/icons/98766de.gif) 表达式:
$ ![](/icons/98766string.gif) =~ m/next|previous/
如果我们希望在这个表达式中使用锚 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 那么我们需要将选项组合起来 ![](/icons/98766dou.gif) 就像在算术中使用圆括号那样 ![](/icons/98766dou2.gif) 因此 ![](/icons/98766dou.gif) 如果我们希望只匹配 ![](/icons/98766zifu.gif) 串开头部分 ![](/icons/98766de.gif) “next”或“previous” ![](/icons/98766dou.gif) 可以这样写表达式:
$ ![](/icons/98766string.gif) =~ m/^(next|previous)/
我们把所有这些操作符叫做原子操作符 ![](/icons/98766dou.gif) 就是说 ![](/icons/98766dou.gif) 它们和 ![](/icons/98766yi.gif) 个单独 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 相对应 ![](/icons/98766dou2.gif) 不过 ![](/icons/98766dou.gif) 常规表达式 ![](/icons/98766de.gif) 实际长度取决于操作 ![](/icons/98766de.gif) 是循环次数 ![](/icons/98766dou2.gif) 为介绍说明这个问题 ![](/icons/98766dou.gif) 我们以确定 ![](/icons/98766yi.gif) 个 ![](/icons/98766zifu.gif) 串中是否包含 ![](/icons/98766yi.gif) 个有效电话号码为例 ![](/icons/98766dou2.gif) 我们可以使用“glob”操作符 ![](/icons/98766dou.gif) 它写作“*” ![](/icons/98766dou2.gif) 许多以某种形式使用命令行 ![](/icons/98766de.gif) 人都熟悉“*”用作通配符 ![](/icons/98766de.gif) 情况 ![](/icons/98766dou.gif) 在Perl中它也有相似 ![](/icons/98766de.gif) 使用方法 ![](/icons/98766dou.gif) 匹配任何数量 ![](/icons/98766de.gif) 前 ![](/icons/98766yi.gif) 个 ![](/icons/98766zifu.gif) 构成 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou2.gif) 因此:
$ ![](/icons/98766string.gif) =~ m/a*/
匹配由任意个a构成 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou2.gif) 现在我们匹配任意个数字:
$ ![](/icons/98766string.gif) =~ m/[0-9]*/
这并不是我们所需要 ![](/icons/98766de.gif) 表达式 ![](/icons/98766dou.gif) ![](/icons/98766yinwei.gif) 它和任意数字 ![](/icons/98766dou.gif) 甚至是零相匹配 ![](/icons/98766dou2.gif) 我们本可以用“+”代替“*” ![](/icons/98766dou.gif) 它匹配 ![](/icons/98766yi.gif) 个或几个开始 ![](/icons/98766de.gif) 那个 ![](/icons/98766zifu.gif) ![](/icons/98766dou.gif) 但这无法解决查找到 ![](/icons/98766de.gif) 数字太长或太短 ![](/icons/98766de.gif) 问题 ![](/icons/98766dou2.gif) 我们真正需要 ![](/icons/98766de.gif) 是指定循环 ![](/icons/98766de.gif) 次数 ![](/icons/98766dou.gif) 在这个例子中为 7次 ![](/icons/98766dou2.gif) 这时我们可以使用大括号:
$ ![](/icons/98766string.gif) =~ m/^[0-9]$/
这个结果更接近我们 ![](/icons/98766de.gif) 目 ![](/icons/98766de.gif) ![](/icons/98766dou.gif) 它匹配包含 7个数字 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou2.gif) 大括号有另外 ![](/icons/98766yi.gif) 些选项 ![](/icons/98766dou.gif) 使它们在指定循环时功能更加强大 ![](/icons/98766dou.gif) 例如 ![](/icons/98766dou.gif) 你可以指定循环范围:
$ ![](/icons/98766string.gif) =~ m/[0-9]/
这将匹配包含6个或8个数字 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou.gif) 但如果我们用“”代替“” ![](/icons/98766dou.gif) 就可以匹配6位或6位以上 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串;而“”则匹配8位或8位以下 ![](/icons/98766de.gif) ![](/icons/98766zifu.gif) 串 ![](/icons/98766dou2.gif)
我们再看 ![](/icons/98766yi.gif) 下那些电话号码 ![](/icons/98766dou.gif) 现在它能够正常匹配 ![](/icons/98766dou.gif) 但仍然存在太多限制 ![](/icons/98766dou2.gif) 不管什么时候 ![](/icons/98766dou.gif) 在处理用户输入时 ![](/icons/98766dou.gif) 你必须指望人们以各种方式进行简单操作 ![](/icons/98766dou2.gif)
尝试和预见 ![](/icons/98766yi.gif) 些更加常见 ![](/icons/98766de.gif) 电话号码格式可能是个好主意 ![](/icons/98766dou2.gif) 举 ![](/icons/98766yi.gif) 个简单 ![](/icons/98766de.gif) 例子 ![](/icons/98766dou.gif) 如号码“2391720” ![](/icons/98766dou.gif) 它能够以“239-1720”或“239 1720” ![](/icons/98766de.gif) 形式输入 ![](/icons/98766dou2.gif) 现在我们可以使用圆括号来匹配“-”或“” ![](/icons/98766dou.gif) 但我们需要新操作符来处理根本没有分隔符 ![](/icons/98766de.gif) 情况:即“?”操作符 ![](/icons/98766dou.gif) 表示前面可以有也可以没有 ![](/icons/98766zifu.gif) ![](/icons/98766dou2.gif) 我们可以用下面 ![](/icons/98766de.gif) 表达式匹配所有这 3种格式:
$ ![](/icons/98766string.gif) =~ m/[0-9][- ]?[0-9]/
同样 ![](/icons/98766dou.gif) 我们查看 ![](/icons/98766yi.gif) 下服务部门 ![](/icons/98766de.gif) 号码 ![](/icons/98766dou2.gif) 澳大利亚电话号码中有 ![](/icons/98766yi.gif) 个两位数 ![](/icons/98766de.gif) 区号 ![](/icons/98766dou.gif) 我们在下面 ![](/icons/98766de.gif) 表达式中增加它们:
$ ![](/icons/98766string.gif) =~ m/([0-9][- ]?)?[0-9][- ]?[0-9]/
这个表达式可以匹配“02 114 7682”这样 ![](/icons/98766de.gif) 电话号码 ![](/icons/98766dou.gif) 而且 ![](/icons/98766dou.gif) ![](/icons/98766yinwei.gif) 我们把区号部分放在圆括号中 ![](/icons/98766dou.gif) 使它成为可选内容 ![](/icons/98766dou.gif) 所以这个表达式还可以匹配前 ![](/icons/98766yi.gif) 个表达式匹配 ![](/icons/98766de.gif) 格式 ![](/icons/98766dou2.gif) 我们还可以做出更多改进 ![](/icons/98766dou.gif) 如把区号放在“(”和“)”中;但是 ![](/icons/98766dou.gif) 如你所见 ![](/icons/98766dou.gif) 你在表达式中增加越多选项 ![](/icons/98766dou.gif) 表达式就会越长越复杂 ![](/icons/98766dou.gif) 因此到底是否增加更多选项 ![](/icons/98766dou.gif) 由你自己决定 ![](/icons/98766dou2.gif)
下次我们将深入讨论常规表达式 ![](/icons/98766de.gif) 使用方法 ![](/icons/98766dou.gif) 包括替代、转换和如何建立你需要 ![](/icons/98766de.gif) Perl常规表达式 ![](/icons/98766chengxu.gif)
相关文章
读者评论
发表评论
|
|