Регулярное выражение Python для блоков значений ключа, разделенных пробелами, в список словарей - PullRequest
0 голосов
/ 14 октября 2019

У меня большой многострочный текст строк значения ключа, разделенных пробелами и разделенных на блоки с использованием символов ====. Для каждого блока я хочу создать словарь с ключом-значением

По сути, я обнаружил, что пишу регулярное выражение гораздо труднее, чем создаю словарь, я использовал этот r'^(\w+)\s*(.*)', чтобы получить ключ и значение как бы то ни былопосле пробела, но я не знаю, как разделить текст на блоки с помощью ====. Значения, очевидно, являются поддельными, однако каждое значение может перетекать на новую строку, как вы можете видеть ниже.

См. Текст ниже:

name                  jcento                                                                                                                                                                        
server_param          uptime=2,load=2, \                                                                                                                                                
                      mem=1,io=10
info_values           cpu=5,io=1,load=0, \                                                                                                                                    
                      core=8, mem=22724, \                                                                                                                                                         

info_value1           10                                                                                                                                                                                            
info_value2           banana                                                                                                                                                                                     
info_value3           NONE                                                                                                                                                                                         
projects              proj1 proj2 proj3 \
                      proj4

info_value5           NONE                                                                                                                                                                                         
info_value6           NONE                                                                                                                                                                                         
info_value7           NONE                                                                                                                                                                                         
info_value8           NONE                                                                                                                                                                                         
info_value9           NONE                                                                                                                                                                                      
================================================================================                                                                                                                                   
name                  jcento                                                                                                                                                                        
server_param          uptime=2,load=2, \                                                                                                                                                
                      mem=1,io=10
info_values           cpu=5,io=10,load=0, \                                                                                                                                                                                                                                                                               
                      core=8, mem=22724, \                                                                                                                                                         

info_value1           10                                                                                                                                                                                            
info_value2           banana                                                                                                                                                                                     
info_value3           NONE                                                                                                                                                                                         
projects              proj1 proj2 proj3 \
                      proj4

info_value5           NONE                                                                                                                                                                                         
info_value6           NONE                                                                                                                                                                                         
info_value7           NONE                                                                                                                                                                                         
info_value8           NONE                                                                                                                                                                                         
info_value9           NONE    

Я ожидаю, что выводом будет список словарей [{name:'jcento', server_param: 'uptime=2,load=2,mem=1,io=1', ...}, {name:'jcento5',....}]

Также, если возможно, создайте регулярное выражение, которое генерируетСловарь из ключа = значение имени, значение = значение проектов, например:

{jcento: 'proj1 proj2 proj3 proj4', jcento5: 'proj1 proj2 proj3 proj4'}.

Заранее спасибо!

1 Ответ

0 голосов
/ 21 октября 2019

Если я правильно вас понимаю, вы хотите, чтобы каждый раздел, разделенный границей "==========", был его уникальным в списке. Вы не предоставили никакого кода, но, увидев, что вы используете это регулярное выражение, чтобы найти пары «ключ / значение»

r'^(\w+)\s*(.*)'

Я предполагаю, что вы захватили две группы и просто передали их соответствующие значения как newDict[match.group(1)] = match.group(2)

Проблема сводится к тому, как вы читаете данные. При таком подходе я просто прочитал бы файл построчно, но поскольку ваши значения могут быть многострочными, я уже не уверен, как вы можете получить правильные группировки из предоставленного вами регулярного выражения. «(. *)» должен быть чертовски жадным и возвращать вам гораздо больше, чем вы хотели бы.

Если все переходы на строки помечены знаком «\», вы можете написать регулярное выражение, которое может принять это вучетная запись, как это: заменить "(. *)" на "([\ w, =] + (\ s \\ s? [\ w, =] +)?)"

Однако я бывозможно, просто внесите определенные изменения в текстовый файл, как я его прочитал, чтобы все точки данных были сохранены в одной строке, прежде чем выполнять итерацию по нему и захватывать его с помощью предыдущего регулярного выражения. Дополнительный бонус: Вы можете добавить строку в функцию итерации, которая соответствует «=========», и инициализировать новый словарь при добавлении старого в список.

   import re
   final_list = []

   def makeDict(fl, data):
        kvPattern = re.compile(r'^(\w+)\s*(.*)')
        newDict = {}
        for line in data:
            if line.startswith("============="):
                fl.append(newDict)
                newDict = {}
            elif kvPattern.search(line):
                match = kvPattern.search(line)
                newDict[match.group(1)] = match.group(2)

        return fl

    final_list = makeDict(final_list, data)

Если вы считаете,дерзкий, вы также можете использовать «else» вместо «elif». Или, что еще лучше, оберните все это в блоки Try, чтобы проверить, не совпадают ли точки данных с вашим шаблоном регулярных выражений

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...