正则表达式语法:功能丰富的Perl: Perl6语法和正则表达式来源: 发布时间:星期四, 2009年2月12日 浏览:54次 评论:0
Perl 6 终于即将面世在本文中Ted 将向您介绍 Perl 6 语言语法和正则表达式并将它们和当前可用 Perl 5 Parse::RecDescent 模块进行对比认识 Perl 正则表达式新特性并学会如何具体使用新奇而又功能强大 Perl 脚本语言 对所有 Perl 编程人员而言Perl 6 项目是个热门话题Perl 直是门不断发展语言几乎从任何可以想像得到角度都可以确定Perl 6 确实是由 Perl 5 进化而来(不过您也可以说它们起源相同)Perl 6 将运行于 Parrot 的上Parrot 是种通用虚拟机不但可以加载和解释 Perl 6 字节码还可以加载和解释其他许多语言 不要让将来问题困扰着您如果您曾经用了几个月时间来观察某个建筑物建筑过程您就会知道选好地基后要进行挖掘金属骨架似乎总是矗立着工人们来来往往工作直在进行但是表面看到却总是陈旧、丑陋、生锈金属然后若干天以后突然间建筑物就完成了Perl 6 项目当前正是处于那个长期中间阶段表面看到只是生锈金属而工人们正在深入地下进行幕后工作如果您想洞悉项目进展那么可以去查看最新 Parrot 发行版本以及 Perl 6 每周更新(请参阅参考资料中链接) 本文将向您介绍 Perl 6 语言语法和正则表达式并将这些和当前可用 Perl 5 Parse::RecDescent 模块进行对比如果以前对 Perl 5 有所了解熟悉 Parse::RecDescent并且有词法分析(lexing)和句法分析(parsing)方面经验那么这些会对您掌握本文有很大帮助此外本文是为那些对 Perl 6 语法和正则表达式感兴趣所有 Perl 编程人员撰写 Perl 6 正则表达式和语法概述 首先需要声明件事:Perl 将通过使用 :p5 修饰符来支持 Perl 5 正则表达式对于那些对 Perl 6 正则表达式不感兴趣或者不想转到这方面来人而言这是个福音此外Perl 6 正则表达式可能(但不是必须)和 Perl 5 中对应正则表达式有本质上区别 在需要时Perl 6 正则表达式可以被复用在匹配单词时复用正则表达式是很荒谬;但在解析配置文件时几乎必须要复用正则表达式(这取决于配置文法复杂度、发生修改频率等) 在 Perl 5 中Regexp::Common 模块(请参阅参考资料)已经在尝试复用正则表达式但是 Perl 5 不允许复用正则表达式所以不得不将它们封装在个模块接口中 Perl 6 完全支持这种复用 尽管您可以编写类似 Perl 5 正则表达式模糊而晦涩 Perl 6 正则表达式但在默认情况下允许启用空格注解;所以虽然在 Perl 5 中您可以用“hello there”本身来匹配“hello there”但在 Perl 6 中您必须将其改为 /hello <sp> there/这样就可以在正则表达中将条件清晰地分离开来 更重要是在语法(grammars)内部使用正则表达式时Perl 6 正则表达式必须不那么晦涩编程人员会发现(我希望如此 Larry Wall 也是)对清单 2 理解和维护要比对清单 1 容易得多: 清单 1. 没有语法正则表达式 # note this is just a language example, not an accurate name matcher # Perl 6 <[A-Z]> is equivalent to the Perl 5 [A-Z] # Perl 6 :w modier surrounds all tokens with "automagic" whitespace, # which basically means it will match what most people would call # "words" $name = m:w/ <[A-Z]><[a-z]>+ <[A-Z]><[a-z]>+ /; 清单 2. 在语法中作为规则正则表达式 # note this is just a language example, not an accurate name matcher grammar English { rule name :w { <singlename> <singlename> }; rule singlename { <[A-Z]><[a-z]>+ }; }; 清单 2 不仅更容易读懂而且维护起来也更容易例如Perl 6 本身已经定义了 <upper> 和 <lower> 规则这使事情变得更为简单: 清单 3. 在语法中作为规则经过改进正则表达式 # note this is just a language example, not an accurate name matcher grammar Names { rule name :w { <singlename> <singlename> }; rule singlename { <upper><lower>+ }; }; 瞧!使用 <upper> 和 <lower> 的后我们就复用了代码此外我们现在还可以处理 Unicode 名称而这的前我们只能局限于处理从 A 到 Z 开头名称代码复用是项出色技术 在进行更进步维护时几乎总是需要对名称中破折号或其他名称(比如 Don Quixote de la Mancha)进行修正(举例来说)同样在将对个别规则更改隔离出来或者在需要时创建个新规则时候您会注意到这是多么简单 语法(Grammars) 是相当简单概念它们是具有专用名称空间()和专用子例程包;每个子例程被称为个规则语法可以继承其他语法这样就使得编程人员既可以复用其他人代码也可以编写能够复用代码从 Perl 模块 CPAN 存档文件(archive)获得成功中可以明显地看出这种复用价值Perl 6 语法在规则中使用正则表达式然后可以将这些规则用于其他规则的中 对比 Parse::RecDescent 和 Perl 6 语法 熟悉 Parse::RecDescent 人都知道它是个功能强大工具Parse::RecDescent 是个 Perl 5 模块只使用很少代码就可以生成非常强大语法这些语法和 Perl 6 语法是否非常相似呢?是这样Parse::RecDescent 作者 Damian Conway 深入参和了 Perl 6 许多工作因此很多在 Parse::RecDescent 中证明好用思想都被应用到 Perl 6 中也就不足为奇了它们些语法有很多类似的处 Parse::RecDescent(此后称的为 P::RD)使用 模块文法来创建新语法每个 P::RD 语法成为 P::RD 类中个对象语法中每个规则都可以作为用来执行动作思路方法P::RD 语法可以将动作(action)和每个规则关联起来将其作为解析过程中个完整部分在 Perl 5 本身中解析是个事件而使用了扩展语法动作则是达成目标途径中不幸牺牲品(roadkill)那些扩展语法被证明是造成迷惑罪魁祸首这区别使得 P::RD 比 Perl 5 正则表达式更为有效原因在于当检测到匹配对象时它会使某些事情发生 Perl 6 语法吸取了 P::RD 经验它意识到了这些动作实用性现在这些动作已经成为其首要组成部分每发现个匹配对象就会执行个动作(代码块)即使匹配对象内容可能已经被修改也是如此!此外这些动作语法和 P::RD 中语法同样简单 清单 4. 包含动作 Parse::RecDescent 语法 # small extract from my cfperl.pl program's global parser my $parse_global = Parse::RecDescent (q{ input: blank | comment | | section comment: /^\s*/ '#' { 1; } blank: /^\s*$/ { 1; } section: /\w+/ ':' { $::current_section = $item[1]; $::current_es = 'any'; 1; } : compound_ '::' { $::current_es = $item{compound_}; 1; } compound_: /[-!.|\w]+/ }); $parse_global->input("TEXT GOES HERE"); 上面语法只有个规则即 input它将匹配 blank、comment、 或者 section 规则这些规则中每个规则都有个定义它们可以是独立或是基于另个规则也可以同时具备这两种特性 注意像普通代码块那样封装在大括号 { } 内动作对于个片断(section)动作将全局变量 $current_section 设置为正在进行匹配片断并重新设置 $current_es 全局变量对于类动作将全局 $current_es 变量设置为匹配条目 这个语法在 Perl 6 中会是什么样呢? 清单 5. 清单 4 语法 Perl 6 译本 # this may be buggy - it's certainly untested # every input is known to be _disibledevent=> $::current_es = 'any'; } } rule { (<compound_>) \s* \:\: { $::current_es = $1; } } rule compound_ { <[-!.|\w]>+ } } Perl 5 正则表达式 如果您对 Perl 5 正则表达式非常熟悉那么可以跳过这节 所有 Perl 5 编程人员都熟悉 Perl 5 正则表达式在进行匹配时要用 m// 操作符来标识这些正则表达式(有时是可选)而当匹配并替换时则要用 s/// 操作符来标识它们在特定情况下/ 可以由其他取代并且有些特定操作符它们和正则表达式有几分类似不过这样操作符不多(例如 tr///)Perl 5 正则表达式要指明或者是“寻找此内容”或者是“寻找此内容并 0
相关文章读者评论发表评论 |