2016-08-01 3 views
-1

У меня есть файл конфигурации, из которого мне нужно извлечь только некоторые значения. Например, у меня есть это:Regex, чтобы соответствовать только определенной строке

PART 
{ 
    title = Some Title 
    description = Some description here. // this 2 params are needed 
    tags = qwe rty // don't need this param 
    ... 
} 

Мне нужно извлечь значение определенных пар, например description «ы значения. Как это сделать в Python3 с регулярным выражением?

ответ

1

Вот регулярное выражение, при условии, что текстовый файл находится в txt:

import re 

m = re.search(r'^\s*description\s*=\s*(.*?)(?=(//)|$)', txt, re.M) 
print(m.group(1)) 

Позвольте мне объяснить. ^ спички в начале строки. Тогда \s* означает ноль или больше пробелов (или вкладок) description - ваш якорь для нахождения значения. После этого мы ожидаем, что знак = с дополнительными пробелами до или после, обозначив \s*=\s*. Затем мы снимаем все после = и дополнительных мест, обозначая (.*?). Это выражение захватывается скобками. В круглой скобке мы говорим что-либо (точка) столько раз, сколько вы можете найти (звездочку) в не жадности (вопросительный знак), т. Е. Остановить, как только будет найдено следующее выражение.

Следующее выражение представляет собой выражение lookahead, начиная с (?=, которое соответствует значению сразу после (?=. И это на самом деле две опции, разделенные вертикальной чертой |.

Первый вариант, слева от панели, говорит // (в скобках, чтобы сделать его атомным блоком для операции выбора вертикальной полосы), то есть начало комментария, которое, я полагаю, вы не хочу захватить. Второй вариант: $, что означает конец строки, который будет достигнут, если на линии не будет комментариев //. Итак, мы ищем все, что можем, после первого знака =, пока мы не встретим шаблон //, или мы встретим конец линии. В этом суть части (?=(//)|$).

Нам также нужен флаг re.M, чтобы сообщить двигателю регулярного выражения, что мы хотим ^ и $ соответствуют началу и концу строк соответственно. Без флага они соответствуют началу и концу всей строки, чего мы не хотим в этом случае.

-1

Это довольно простое регулярное выражение, вам просто нужен положительный lookbehind и, возможно, что-то, чтобы удалить комментарии. (Сделать это путем добавления ?(//)? в регулярном выражении)

r"(?<=description =).*" 

Regex101 demo

+0

комментарии были добавлены мной только для claryfying: P – Kerbiter

+0

Это будет соответствовать строке документа. – Kasramvd

+0

Что такое «строка документа»? – RamenChef

0

Лучше подход будет использовать установленный файл конфигурации системы. Python имеет встроенную поддержку INI-подобных файлов в модуле configparser.

Однако, если вы просто отчаянно нужно получить строку текста в этом файле после description, вы можете сделать это:

def get_value_for_key(key, file): 
    with open(file) as f: 
     lines = f.readlines() 
    for line in lines: 
     line = line.lstrip() 
     if line.startswith(key + " ="): 
      return line.split("=", 1)[1].lstrip() 

Вы можете использовать его с вызовом, как: get_value_for_key("description", "myfile.txt"). Метод вернет None, если ничего не найдено. Предполагается, что ваш файл будет отформатирован там, где есть пробел и знак равенства после имени ключа, например. key = value.

Это позволяет полностью избежать регулярных выражений и сохраняет любые пробелы в правой части значения. (Если это не для вас важно, вы можете использовать strip вместо lstrip.)

Почему бы не написать регулярные выражения? Они дороги и действительно не идеальны для этого сценария. Используйте простое сопоставление строк. Это позволяет избежать импорта модуля и упрощает ваш код. Но на самом деле я бы сказал, чтобы преобразовать в поддерживаемый формат файла конфигурации.

Смежные вопросы