Преобразование текстового файла в YAML в Python - PullRequest
0 голосов
/ 03 августа 2020

У меня есть текстовый файл для преобразования в формат YAML. Вот несколько примечаний, чтобы лучше описать проблему:

  • Разделы в файле имеют разное количество подзаголовков относительно друг друга.
  • Значения подзаголовков могут быть любыми тип данных (например, string, bool, int, double, datetime).
  • Длина файла составляет примерно 2000 строк.

Пример формата ниже:

file_content = '''
    Section section_1
        section_1_subheading1 = text
        section_1_subheading2 = bool
    end
    Section section_2
       section_2_subheading3 = int
       section_2_subheading4 = double
       section_2_subheading5 = bool
       section_2_subheading6 = text
       section_2_subheading7 = datetime
    end
    Section section_3
       section_3_subheading8 = numeric
       section_3_subheading9 = int
    end
'''

Я попытался преобразовать текст в формат YAML следующим образом:

  1. Замена знаков равенства двоеточиями с помощью регулярного выражения.
  2. Замена Section section_name на section_name :.
  3. Удаление end между каждым разделом.

Однако у меня возникли трудности с # 2 и # 3. Это функция преобразования текста в YAML, которую я создал:

import yaml
import re

def convert_txt_to_yaml(file_content):
    """Converts a text file to a YAML file"""

    # Replace "=" with ":"
    file_content2 = file_content.replace("=", ":")

    # Split the lines 
    lines = file_content2.splitlines()

    # Define section headings to find and replace
    section_names = "Section "
    section_headings = r"(?<=Section )(.*)$"
    section_colons = r"\1 : "
    end_names = "end"

    # Convert to YAML format, line-by-line
    for line in lines:
        add_colon = re.sub(section_headings, section_colons, line) # Add colon to end of section name
        remove_section_word = re.sub(section_names, "", add_colon) # Remove "Section " in section header
        line = re.sub(end_names, "", remove_section_word)          # Remove "end" between sections

    # Join lines back together
    converted_file = "\n".join(lines)
    return converted_file

Я считаю, что проблема в for l oop - я не могу понять, почему этот раздел заголовки и окончания не меняются. Он отлично печатает, если я его проверяю, но сами строки не сохраняются.

Я ищу следующий формат вывода:

file_content = '''
    section_1 :
        section_1_subheading1 : text
        section_1_subheading2 : bool
    section_2 :
        section_2_subheading3 : int
        section_2_subheading4 : double
        section_2_subheading5 : bool
        section_2_subheading6 : text
        section_2_subheading7 : datetime
    section_3 :
        section_3_subheading8 : numeric
        section_3_subheading9 : int
'''

1 Ответ

1 голос
/ 03 августа 2020

Я бы предпочел преобразовать его в dict, а затем отформатировать как yaml, используя пакет yaml в python, как показано ниже:

import yaml
def convert_txt_to_yaml(file_content):
    """Converts a text file to a YAML file"""
    config_dict = {}
    
    # Split the lines 
    lines = file_content.splitlines()
    section_title=None
    for line in lines:
        if line=='\n':
            continue
        elif re.match('.*end$', line):
            #End of section
            section_title=None
        elif re.match('.*Section\s+.*', line):
            #Start of Section
            match_obj =  re.match(".*Section\s+(.*)", line)
            section_title=match_obj.groups()[0]
            config_dict[section_title] = {}
        elif section_title and re.match(".*{}_.*\s+=.*".format(section_title), line):
            match_obj =  re.match(".*{}_(.*)\s+=(.*)".format(section_title), line)            
            config_dict[section_title][match_obj.groups()[0]] = match_obj.groups()[1]
    return yaml.dump(config_dict )
...