【问题标题】:Parse ~4k files for a string (sophisticated conditions)为字符串解析 ~4k 文件(复杂条件)
【发布时间】:2018-05-17 23:32:14
【问题描述】:

问题描述

有一组~4000个python文件,结构如下:

@ScriptInfo(number=3254,
            attibute=some_value,
            title="crawler for my website",
            some_other_key=some_value)

scenario_name = entity.get_script_by_title(title)

目标

目标是从 ScriptInfo 装饰器中获取标题的值(在本例中是“我的网站的爬虫”),但有几个问题:

1) 没有命名包含标题的变量的规则。这就是为什么它可以是 title_name、my_title 等。参见示例:

@ScriptInfo(number=3254,
            attibute=some_value,
            my_title="crawler for my website",
            some_other_key=some_value)

scenario_name = entity.get_script_by_title(my_title)

2) @ScriptInfo 装饰器可能有两个以上的参数,因此从括号之间获取其内容以获取第二个参数的值不是一种选择

我的(非常天真的)解决方案

但保持不变的代码是scenario_name = entity.get_script_by_title(my_title) 行。考虑到这一点,我想出了解决方案:

import re
title_variable_re = r"scenario_name\s?=\s?entity\.get_script_by_title\((.*)\)"
with open("python_file.py") as file:
    for line in file:
        if re.match(regexp, line):
            title_variable = re.match(title_variable_re, line).group(1)
title_re = title_variable  + r"\s?=\s\"(.*)\"?"
with open("python_file.py") as file:
    for line in file:
        if re.match(title_re, line):
            title_value = re.match(regexp, line).group(1)
print title_value 

这段代码执行以下操作:

1) 遍历(参见第一个with open)脚本文件并获取具有title 值的变量,因为由程序员选择其名称 2)再次遍历脚本文件(见第二个with open),获取title的值

stackoverflow 家族的问题

有没有比遍历脚本文件两次更好更有效的方法来获取标题(my_title's、title_name's 等)的值?

【问题讨论】:

  • 首先,您可以在找到匹配项后跳出循环。除非您期望有多个匹配项,否则文件后面的匹配项应该覆盖文件前面的匹配项。
  • 每个文件是否有多个 @ScriptInfo ... scenario_name = ... 对?如果是这样,它们是否总是有序的(即scenario_name 是否总是遵循@ScriptInfo... 结构)?最后,除了这两种结构之外,您的文件还有其他内容吗?

标签: python parsing text-parsing


【解决方案1】:

如果您只打开文件一次并将所有行保存到fileContent,在适当的地方添加break,并重新使用匹配项来访问捕获的groups,您会得到类似这样的内容(@987654324 后面有括号@ 用于 3.x,不用于 2.7):

import re

title_value = None 

title_variable_re = r"scenario_name\s?=\s?entity\.get_script_by_title\((.*)\)"
with open("scenarioName.txt") as file:
    fileContent = list(file.read().split('\n'))
    title_variable = None
    for line in fileContent:
        m1 = re.match(title_variable_re, line)
        if m1:
            title_variable = m1.group(1)
            break
    title_re = r'\s*' + title_variable  + r'\s*=\s*"([^"]*)"[,)]?\s*'
    for line in fileContent:
        m2 = re.match(title_re, line)
        if m2:
            title_value = m2.group(1)
            break
print(title_value)

这里是一个未排序的正则表达式变化列表:

  • title_variable 之前留出空格,这就是r'\s*' + 的用途
  • = 周围留出空间
  • title_re 中的行尾允许逗号或右圆括号,这就是 [,)]? 的用途
  • 在行尾留出一些空格

在以下文件作为输入进行测试时:

@ScriptInfo(number=3254,
        attibute=some_value,
        my_title="crawler for my website",
        some_other_key=some_value)

scenario_name = entity.get_script_by_title(my_title)

它产生以下输出:

crawler for my website

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-06-20
    • 2012-05-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-15
    相关资源
    最近更新 更多