您好,欢迎访问三七文档
当前位置:首页 > 临时分类 > Pyparsing中文教程V2
Pyparsing导引byPauMcGuire你需要从文本文件或网页中提取数据吗?或者你想要更人性化的用户命令接口或者搜索字符串?正则表达式和lex/yacc让你的眼睛和脑袋疼?Pyparsing将成为解决方案。Pyparsing是纯python的类库,其能让你容易的建立递归下降(recursive-descent)解析器。这不需要你自己写个解析器。只要使用pyparsinng,你能够解析HTML,轻松建立日志文档数据提取器,复杂数据结构以及命令解释器。这个ShortCut将告诉你怎么做!Pyparsing导引Pyparsing是什么?Pyparsing程序的简单形式从Pyparsing出引用名字定义语法使用语法解析输入文本处理解析后的文本“Hello,World”在Steroids什么使得Pyparsing变得不同?类名比特殊符号好读并且好理解语法定义中的空格的扰乱结果应当比单纯的列表形式多更多东西在解析时间就执行的预处理语法必须对改变具有更强的适应性和健壮性从表格文件中解析数据-使用解析行为和ParseResults从网页数据中提取数据一个简易S表达式解析器一个完整的S表达式解析器解析搜索字符串100行代码以内的搜索引擎结论索引“我需要解析这个日志文件…”“只是要从网页中提取数据…”“我们需要一个简单的命令行解释器…”“我们的源代码需要移植到新API集上…”这些工作要求每天都让开发者们条件反射般的骂娘”擦,又要一个解析器!”解析不十分严格格式的数据形式的任务经常出现在开发者面前。有时其是一次性的,像内部使用的API升级程序。其他时候,解析程序作为在命令行驱动的程序中的内建函数。如果你在Python中变成,你可以脱离这些工作,通过使用Python的内建字符串方法,比如split(),index()以及startwith().让这项工作又变得讨厌的是我们经常不只是对字符串分割和索引,对于一些内容可变形式或复杂的语法定义来说。比如:y=2*x+10(每个符号间都有空分隔)是容易解析的,对于这种空格分离的形式。不幸的是,很少有用户会如此这般使用空格,算术表达式经常像这样:y=2*x+10y=2*x+10y=2*x+10直接对昀后一个字符串运用split方法会导致返回原字符串(作为一个列表的唯一实例),不会分离出这些单独的元素y,=2,等等.处理这种超越str.split的解析任务的工具是正则表达式或lex/yacc。正则表达式用一个字符串去描述文本模式以便匹配。那个字符串使用特殊符号(像|,+,.,*,?)去表示不同的解析概念像alternation(多选),repetition(重复)以及wildcards(通配符).Lex/yacc是则先拆出标记,然后应用过程代码到解压出的标记上。Lex/yacc使用一个单独的标记定义文件,然而产生lex中间文件以及标记过程代码模板给程序员扩展,以驱动程序的特殊行为。历史注释这些文本处理技术昀早在1970年以C实现,现在它们仍在广大的领域发挥作用。Python通过re模块以及”batteriesincluded”的部分标准库提供了对正则表达式的支持。你可以下载一些免费的lex/yacc风格的解析器模块,其提供了对python的接口。这些传统工具的主要问题在于它们独特的标记系统需要被精确映射到Python的代码上。比如lex/yacc风格工具往往要单独进行一个代码产生阶段。实践中,解析器编写看起来陷入一个怪圈中:写代码,解析示例文本,找到附加的特殊情况等等。组合正则表达式符号,额外的代码生成步骤,很这个循环过程可能会不断的陷入挫折。Pyparsing是什么?Pyparsing是纯python编写的,易于使用。Pyparsing的类库提供了一系列类让你可以从表达式单独的元素中开始构建解析器。其表达式使用直觉的符号组合,如+表示将一个表达式加到另一个后面。|,^表示解析多选(意为匹配第一个或匹配昀长的).表达式的返回值修饰以类的形式追加,如OneOrMore,ZeroOrMore,Optional.作为例子,一个正则表达式处理IP地址后面跟着一个US风格的电话号码需要这样写:(\d{1,3}(?:\.\d{1,3}){3})\s+(\(\d{3}\)\d{3}-\d{4})对比一下,类似的表达式用pyparsing写是这个样子ipField=Word(nums,max=3)ipAddr=Combine(ipField+.+ipField+.+ipField+.+ipField)phoneNum=Combine((+Word(nums,exact=3)+)+Word(nums,exact=3)+?+Word(nums,exact=4))userdata=ipAddr+phoneNum尽管它使用了更长,但pyparsing版本更易读;它更容易被回朔和更新,比如可以更容易从此迁移去处理其他国家的电话号码格式,Python新手?我已经收到很多邮件,他们告诉我使用pyparsing也是他们第一次使用python编程。他们发现pyparsing易于得到,而且还有好读的例子。如果你是刚开始使用python,你肯恩感到一点困难阅读这些例子。Pyparsing不要求任何高级的python只是,它易于学习。有一些网络教程资源,比如python的官网。[].为了更好的使用pyparsing,你应当更熟悉python的语言特性,如缩进语法,数据类型,以及foriteminitemSequence:式循环控制语法Pyparsing使用object.attribute式标记,就像python的内建容器类,元组,表以及字典。这本书的例子使用了python的lambda表达式,本质上就是单行函数;lambda表达式特别有用于定义简单的解析操作时。列表解析和生成器表达式的迭代形式是有用的,在解析标记结果时,但并不是必须的。Pyparsing是:100%纯python,没有编译过的动态链接库(DLLs)或者共享库包含其中,所以你可以使用它在任何平台在python2.3能够编译的地方。驱动解析表达式的被内联(inline)编码,使用标准的python类标记和符号-没有单独的代码产生过程也没有特殊符号和标记,这将是你的应用易于开发,理解和维护。类似的表达形式:C,C++,Java,Python,HTML注释引号字符串(使用单个或双引号,除了\’,\”转义情况外)HTML与XML标签(包含上下级以及属性操作)逗号分隔以及被限制的列表表达式轻量级封装-Pyparsing的代码包含在单个python文件中,容易放进site-packages目录下,或者被你的应用包含。慷慨的许可证-MIT许可证允许任意商用或非商用。Pyparsing程序的简单形式典型的pyparsing程序具有以下结构:importpyparsing模块使用pyparsing类和帮助方法定义语法使用语法解析输入文本处理从解析出的文本从Pyparsing出引用名字通常,使用frompyparsingimport*是不被python风格专家鼓励的。因为它污染了本地变量命名空间,因其从不明确的模块中引入的不知道数量的名字。无论如何,在pyparsing开发工作中,很难想象pyparsing定义的名字会被使用,而且这样写简化了早期的语法开发。在语法昀终完成后,你可以回到传统风格的引用,或from你需要的那些名字。定义语法语法是你的定义的文本模式,这个模式被应用于输入文本提取信息。在pyparsing中,语法由一个或多个Python语句构成,而模式的组合则使用pyparsing的类和辅助对象去指定组合的元素。Pyparsing允许你使用像+,|,^这样的操作符来简化代码。作为例子,假如我使用pyparsing的Word类去定义一个典型的程序变量名字,其由字母符号或字母数字或下划线构成。我将以Python语句这样描述:identifier=Word(aphas,alphanus+'_')我也想解析数字常数,如整数和浮点数。另一个简化过的定义的Word对象,它应当包含数字,也许还包含小数点。number=Word(num+'.')从这里,我然后定义一个简单的赋值语句像这样:assignmentExpr=identifier+=+(identifier|number)现在我们可以解析像这样的内容了:a=10a_2=100pi=3.14159goldenRatio=1.61803E=mc2在程序的这个部分,你可以附加任何解析时回调函数(或解析动作parseactions)或为语法定义名字去减轻之后指派它们的工作。解析动作是非常有力的特性对于pyparsing,之后我们将论述它的细节,实践:BNF范式初步在写python代码实现语法之前,将其先写在纸上是有益的,如:帮助你澄清你的想法指导你设计解析器提前演算,就像你在执行你的解析器帮助你知道设计的界限幸运的是,在设计解析器过程中,有一个简单的符号系统用来描绘解析器,它被称为BNF(Backus-NaurForm)范式.你可以在这里获得BNF的好例子:你并不需要十分严格的遵循它,只要它能刻画你的语法想法即可。在这本书里我们用到了这些BNF记号:::=表示”被定义为”+表示“一个或更多”*表示“零个或更多”被[]包围的项是可选的连续的项序列表示被匹配的标记必须在序列中出现|表示两个项之一会被匹配使用语法解析输入文本在早期版本的pyparsing中,这一步被限制为使用parseString方法,像这样:assignmentTokens=assignmentExpr.parseString(pi=3.14159)来得到被匹配的标记。现在你可以使用更多的方法,全部列举如下:parseString应用语法到给定的输入文本(从定义上看,如果这个文本可以应用多次规则也只会运用到第一次上)scanString这是个生成器函数,给定文本和上界下界,其会试图返回所有解析结果searchStringscanString的简单风光,返回你给定文本的全部解析结果,放在一个列表中。transformStringscanString的另一个封装,还附带了替换操作。现在,让我们继续研究parseString,稍后我将给你们展示其他选择的更多细节。处理解析后的文本当然,如何处理解析文本得到的返回值是昀重要的。在大多数解析工具中,通常会返回一个匹配到的标记的列表供未来进一步解释使用。Pyparsing则返回一个更强的对象,被称为ParseResults.在昀简单的形式中,ParseResults可以被打印和连接像python列表一样。作为例子,继续我们赋值表达式的例子,下面的代码:assignmentTokens=assignmentExpr.parseString(pi=3.14159)printassignmentTokens会打印出['pi','=','3.14159']但是ParseResults也支持解析文本中的个域(individualfields),如果语法为返回值的某些成分指派了名字。这里我们通过给表达式里的元素取名字加强它们(左项成为lhs,右项称为rhs),我们就能在ParseResults里连接这些域,就像它们是返回的对象的属性一样。assignmentExpr=identifier.setResultsName(lhs)+=+(identifier|number).setResultsName(rhs)assignmentTokens=assignmentExpr.parseString(pi=3.14159)printassignmentTokens.rhs,isassignedto,assignmentTokens.lhs将打印出3.14159isassignedtopi现在介绍进
本文标题:Pyparsing中文教程V2
链接地址:https://www.777doc.com/doc-5521257 .html