pyparsing:定制自己的解析器

在工作中,经常需要解析不同类型的文件,常用的可能就是正则表达式了,简单点的,可能会使用awk。这里要推荐一种比较小众的方式,使用pyparsing来解析文件。

pyparsing可以做些什么呢?主要可以相当方便地定制自己的tokenizer,因此可以很容易拓展,实现自己的parser

下面看一个traceview的解析例子

16803 AsyncTask #3
16804 pool-2-thread-5
16806 pool-3-thread-1
16807 uil-pool-2-thread-1
16808 uil-pool-2-thread-2
16809 uil-pool-2-thread-3
16810 uil-pool-2-thread-4
Trace (threadID action usecs class.method signature):
16736 xit         0 ..dalvik.system.VMDebug.startMethodTracingFilename (Ljava/lang/String;IIZI)V	VMDebug.java
16804 xit         0 ..com.android.org.conscrypt.NativeCrypto.EVP_DigestUpdate (Lcom/android/org/conscrypt/OpenSSLDigestContext;[BII)V	NativeCrypto.java
16736 xit       218 .dalvik.system.VMDebug.startMethodTracing (Ljava/lang/String;IIZI)V	VMDebug.java
16736 xit       225 android.os.Debug.startMethodTracing (Ljava/lang/String;II)V	Debug.java
16736 xit       230-android.os.Debug.startMethodTracing (Ljava/lang/String;I)V	Debug.java
16736 xit       266-java.lang.reflect.Method.invoke (Ljava/lang/Object;[Ljava/lang/Object;Z)Ljava/lang/Object;	Method.java
16804 ent       528 ..java.lang.ClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java
16804 ent       543 ...java.lang.ClassLoader.loadClass (Ljava/lang/String;Z)Ljava/lang/Class;	ClassLoader.java
16804 ent       548 ....java.lang.ClassLoader.findLoadedClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java
16804 ent       567 .....java.lang.BootClassLoader.getInstance ()Ljava/lang/BootClassLoader;	ClassLoader.java
16804 xit       576 .....java.lang.BootClassLoader.getInstance ()Ljava/lang/BootClassLoader;	ClassLoader.java
16804 xit       681 ....java.lang.ClassLoader.findLoadedClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java
16804 ent       689 ....com.uc.base.aerie.hack.ClassLoaderSupport$a.loadClass (Ljava/lang/String;Z)Ljava/lang/Class;	ProGuard
16804 ent       704 .....java.lang.ClassLoader.getParent ()Ljava/lang/ClassLoader;	ClassLoader.java
8
16804 ent       726 ......java.lang.BootClassLoader.loadClass (Ljava/lang/String;Z)Ljava/lang/Class;	ClassLoader.java
16804 ent       730 .......java.lang.ClassLoader.findLoadedClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java
16804 ent       734 ........java.lang.BootClassLoader.getInstance ()Ljava/lang/BootClassLoader;	ClassLoader.java
16804 xit       740 ........java.lang.BootClassLoader.getInstance ()Ljava/lang/BootClassLoader;	ClassLoader.java
16804 xit       754 .......java.lang.ClassLoader.findLoadedClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java
16804 xit       759 ......java.lang.BootClassLoader.loadClass (Ljava/lang/String;Z)Ljava/lang/Class;	ClassLoader.java
16804 xit       763 .....java.lang.ClassLoader.loadClass (Ljava/lang/String;)Ljava/lang/Class;	ClassLoader.java

这是一部分转换后的原始日志,格式比较标准,因此可以这么定制

import os

from pyparsing import Word, nums, Combine, alphas, Literal, ZeroOrMore, Group,     Suppress

semiFlag = Literal(";")
dotFlag = Suppress(Literal("."))
multiDot = ZeroOrMore(dotFlag)

threadID =Word(nums, max=5)
actionField = Word(alphas)
usecsField = Word(nums, max=8)

clsField = Word(alphas+".")
methodField = Combine("(" + ZeroOrMore(Word(alphas + ";/")) + ")" + Word(alphas + "/") + semiFlag)

regex = threadID + actionField + usecsField + multiDot + Group(clsField + methodField) + clsField

with open(os.path.join(os.getcwd(), "StepBeforeFirstDraw_o.txt"), "rb") as f:
    lineno = 0
    flag = 0
    while 1:
        line = f.readline()
        lineno += 1
        if "threadID action usecs" in line:
            flag = lineno
            continue
        if flag > 0:
            try:
                regex.parseString(line).toXML("")
            except Exception as e:
                pass

解析结果为:

/usr/bin/python2.7 /home/alex/workspace/virtual_space/project/calclex.py
[‘16804‘, ‘ent‘, ‘528‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘543‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘548‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘567‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘576‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘681‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘704‘, [‘java.lang.ClassLoader.getParent‘, ‘()Ljava/lang/ClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘726‘, [‘java.lang.BootClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘730‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘734‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘740‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘754‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘759‘, [‘java.lang.BootClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘763‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘771‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘774‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘809‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘814‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘818‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘822‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘827‘, [‘java.lang.BootClassLoader.getInstance‘, ‘()Ljava/lang/BootClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘842‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘853‘, [‘java.lang.ClassLoader.getParent‘, ‘()Ljava/lang/ClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘xit‘, ‘857‘, [‘java.lang.ClassLoader.getParent‘, ‘()Ljava/lang/ClassLoader;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘861‘, [‘java.lang.ClassLoader.loadClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘865‘, [‘java.lang.BootClassLoader.loadClass‘, ‘(Ljava/lang/String;Z)Ljava/lang/Class;‘], ‘ClassLoader.java‘]
[‘16804‘, ‘ent‘, ‘869‘, [‘java.lang.ClassLoader.findLoadedClass‘, ‘(Ljava/lang/String;)Ljava/lang/Class;‘], ‘ClassLoader.java‘]

这样已经很方便去做二次处理了,而且解析规则的可读性也会比正则的强。

时间: 2024-11-05 14:50:46

pyparsing:定制自己的解析器的相关文章

基于Jquery的XML解析器,返回定制的HTML

依据HTML模板返回解析的XML 依赖jQuery 1.4?1. [代码]基于Jquery的xml解析器并返回定制的HTML     /** *  jQuery插件 *  Author: [email protected] *  Date  : 2011-02-16 *  Params: dom:XMLDocument , *          _default:{ *              reg:匹配标签正则, *              lc:标签左结束符, *          

使用Scala基于词法单元的解析器定制EBNF范式文法解析

一.前言 近期在做Oracle迁移到Spark平台的项目上遇到了一些平台公式翻译为SparkSQL(on Hive)的需求,而Spark采用亲妈语言Scala进行开发.分析过大概需求过后,拟使用编译原理中的EBNF范式模式,进行基于词法的文法解析.于是拟采用传统的正则词法解析到EBNF文法解析的套路来实现,直到发现了StandardTokenParsers这个Scala基于词法单元的解析器类. 二.平台公式及翻译后的SparkSQL 平台公式的样子如下所示: 1 if(XX1_m001[D003

optparse 模块—— 命令行选项的解析器

15.5 optparse 模块--  命令行选项的解析器 注意:从2.7版本后不再使用:optparse模块不推荐使用,python不再更新该模块,后续的发展将推荐使用argparse模块. 支持python2.3及以上版本 optparse模块比旧的getopt模块具有更方便.更灵活.功能更强大的解析命令行选项的库.optparse使用一种更加声明式的命令行解析风格:你创建一个OptionParser实例,填充选项,并解析命令行.optparse允许用户指定选项,使用传统的GNU/POSIX

SpringMVC入门案例及请求流程图(关于处理器或视图解析器或处理器映射器等的初步配置)

SpringMVC简介:SpringMVC也叫Spring Web mvc,属于表现层的框架.Spring MVC是Spring框架的一部分,是在Spring3.0后发布的 Spring结构图 SpringMVC请求流程图 SpringMVC请求流程图语述: request-------->DispatcherServler(中央调度器/前端控制器)-----> HandlerMapping(处理器映射器)------>返回一个执行链----->将执行链转交给HandlerAdap

[转载]开发 Spring 自定义视图和视图解析器

原文出处 http://www.ibm.com/developerworks/cn/java/j-lo-springview/ 概述 Spring 3.0 默认包含了多种视图和视图解析器,比如 JSP.Velocity 视图等,但在某些情况下,我们需要开发自定义的视图及其解析器,以便显示特殊文件格式的视图,我们也可以使用自定义视图及解析器,针对特定的视图做相应的处理.本文将通过一个示例来介绍如何开发 Spring 自定义视图和视图解析器,来显示后缀名为 SWF 的视图,并提供一个简单的注册机制,

spring beans源码解读之--bean definiton解析器

spring提供了有两种方式的bean definition解析器:PropertiesBeanDefinitionReader和XmLBeanDefinitionReader即属性文件格式的bean definition解析器和xml文件格式的bean definition解析器. 我们先从简单的PropertiesBeanDefinitionReader开始深入挖掘. 1. PropertiesBeanDefinitionReader 属性文件bean definition解析器 1.1  

ViewResolver -Springboot中的视图解析器

项目结构如下(Idea) 代码 package com.syu.config; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.View; import org.springframework.web.servlet.ViewResolver;

[Python]HTML/XML解析器Beautiful Soup

[简介] Beautiful Soup是一个可以从HTML或XML文件中提取数据的Python库.即HTML/XMLX的解析器. 它可以很好的处理不规范标记并生成剖析树(parse tree). 它提供简单又常用的导航(navigating),搜索以及修改剖析树的操作.它可以大大节省你的编程时间. [安装] 下载地址:点击打开链接 Linux平台安装: 如果你用的是新版的Debain或ubuntu,那么可以通过系统的软件包管理来安装: $ apt-get install Python-bs4 B

lua标签解析器

lua 标签解析器 概述 一个类xml标签解析函数,将标签解析成Lua中的表结构它可以用来解析简单xml结构,可以作为RichLabel控件的字符串解析组件(其实它现在就是这么用的;-)) 原理 使用lua的模式匹配, 使用了模式串%b<>%b用来匹配对称的字符.常写为 %bxy,x和y是任意两个不同的字符. x作为匹配的开始,y作为匹配的结束.比如,%b<> 匹配以 < 开始,以 > 结束的字符串 要解析的字符串 hello world <div>hell