Разбор ~ 4k файлов для строки (сложные условия) - PullRequest
0 голосов
/ 18 мая 2018

Описание проблемы

Существует набор из ~ 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) и получает значение заголовка

Вопрос к семейству stackoverflow

Есть ли лучший и более эффективный способ получить значение заголовка (my_title, title_name и т. Д.), Чем обход файла скрипта два раза?

1 Ответ

0 голосов
/ 18 мая 2018

Если вы откроете файл только один раз и сохраните все строки в fileContent, добавите break, где необходимо, и повторно используете совпадения для доступа к захваченным group с, вы получите что-то вроде этого (с круглыми скобками после * 1004)* для 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, для этого [,)]?1020 *
  • Разрешить некоторое пространство в конце строки

При проверке следующего файла в качестве ввода:

@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
...