zoukankan      html  css  js  c++  java
  • python 使用命名组合解析结构化文本

    使用命名组合来解析结构化的文本数据

    有时候我们拿到的数据是以文本的形式逐条列出,而在输出文本时为了增加可读性,可能会将数据元素的描述信息写入进去,这样的结构化数据方便人工识别,但是对于数据的二次利用远不如csv,json等结构化数据好用,为了提取其中有用的信息,可以使用python正则库中命名组合的方法来处理。

    官方文档里对命名组合的说明:

    (?P…)命名组合)类似正则组合,但是匹配到的子串组在外部是通过定义的 name 来获取的。组合名必须是有效的Python标识符,并且每个组合名只能用一个正则表达式定义,只能定义一次。一个符号组合同样是一个数字组合,就像这个组合没有被命名一样。

    命名组合可以在三种上下文中引用。如果样式是 (?P<quote>['"]).*?(?P=quote) (也就是说,匹配单引号或者双引号括起来的字符串):

    引用组合"quote"的上下文 引用方法
    在正则式自身内 (?P=quote)
    1
    处理匹配对象 m m.group('quote')
    m.end('quote')`
    传递到 re.sub() 里的 repl 参数中 g
    g<1>

    (?P=name)反向引用一个命名组合;它匹配前面那个叫 name 的命名组中匹配到的串同样的字串。

    但具体怎么用呢?文档里并没有给出实例,这里结合一个具体的例子来说明一下用法:

    例如对于下面的结构化字符串文本:

    Student(name="John", age=18, grade=Grade(subject="English", mark=90))
    

    如果想要拿到学生的各项信息,使用字符串查找会非常麻烦,而且不具有通用性,因此考虑使用python中的命名组合方式来提取。首先分析该字符串文本的结构,一个Student由三个属性组成:姓名name, 年龄age,学科成绩grade,其中grade属性本身也是一个结构化的文本数据,由两部分组成:学科subject和分数mark。

    为了使我们的文本解析正则表达式具有更高的复用性,我们为该条字符串定义两组命名组合student_re和grade_re:

    import re
    
    grade_re = r'Grade[(]subject="(?P<subject>.*)", mark=(?P<mark>d+)[)]'
    student_re = r'Student[(]name="(?P<name>.*)", age=(?P<age>d+), grade={grade}[)]'.format(grade=grade_re)
    

    使用上述字符串进行测试,提取字符串中我们想要的属性字段数据:

    match = re.match(student_re, test_str)
    if match:
        print(match.group('name'))
        print(match.group('subject'))
    

    输出:

    John
    English
    

    结果符合我们的需要。因此我们只需要根据字符串的结构特征,将各字段的属性名称编写成正则命名组合,就能对任意形式的结构化字符串方便地进行提取了!




    纵使疾风起,人生不言弃!
  • 相关阅读:
    RabbitMQ知识点整理12-消费端的确认与拒绝
    RabbitMQ知识点整理11-消费消息
    RabbitMQ知识点整理0-准备工作和记录
    设计模式-23种设计模式
    设计原则-6大设计原则
    super在python 2.7和Python3中的使用
    rest-framework 视图类源码分析
    celery 组件在django环境应用
    rest framwork 4 分页功能
    rest framework 学习 序列化
  • 原文地址:https://www.cnblogs.com/geekHao/p/14566582.html
Copyright © 2011-2022 走看看