python readfile и регулярное выражение сопоставления на основе другого значения строки под совпадением - PullRequest
0 голосов
/ 10 июля 2020

Я просматриваю строки нескольких файлов и мне нужно найти разделы, которые начинаются с:

\[.+\]

Что отлично работает. Но тогда мне нужна только эта строка, которая соответствует , если под ней есть строка, в которой НЕ говорится "disabled = 1" OR "disabled = 1" OR "disabled = true" OR "disabled = true". Проверяйте все строки под ним, пока не будет найден конец файла ИЛИ другой

\[.+\]

. Если раздел НЕ отключен, я хочу захватить эту строку и сохранить ее в массиве. Код для l oop массива и запись нового файла уже работает нормально. Прямо сейчас я получаю ВСЕ строки заголовка в разделах отключены или нет.

Итак, в конце концов, я хочу, чтобы это был мой новый файл на основе приведенного ниже примера:

[header1:name1]
<some new content>

[header3:name3]
<some new content>

[header4:name4]
<some new content>

содержимое одного ФАЙЛА

[header1:name1]
param1 = value1
param2 = value2
param3 = value3
param4 = value4

[header2:name2]
param1 = value1
param2 = value2
param3 = value3
disabled = 1
param4 = value4

[header3:name3]
disabled = 0
param1 = value1
param2 = value2
param3 = value3
param4 = value4

[header4:name4]
param1 = value1
param2 = value2
param3 = value3
param4 = value4
disabled =false

Это небольшая часть большого скрипта, но вот раздел об этом, который у меня пока работает, но он собирает ВСЕ совпадения, даже отключенные, что является проблемой.

ТЕКУЩИЙ КОД

    enabled_list = []
    for root, dirs, files in os.walk((start_folder)):
        for file in files:
            if file.endswith("file.cnf"):
                file_full = ( os.path.join(root, file) )
                if not any(ignore in str(file_full) for ignore in ignore_if_path_contains):
                    if debug:
                        print(file_full)
                    if CheckFilePermission(file_full, "R"):
                        file_full_read = open( (file_full), 'rb' )
                        if (re.search( r'\[.+\]', str(file_full_read.read()) )):
                            if debug:
                                print( "found string in file: "+(file_full) )
                            with open( (file_full), 'r' ) as rfile:
                                for line in rfile.readlines():
                                    if not any(ignore in str(line) for ignore in ignore_if_section_name_contains):
                                        if ( re.search( r'\[.+\]', (line) ) ):
                                            if debug:
                                                print( "found string in line: "+(line) )
                                            enabled_list.append(line)
    enabled_list = list(dict.fromkeys(enabled_list))
    return(enabled_list)

ОБНОВЛЕНИЕ: РАБОЧИЙ КОД Используя предложение от JD Frias ниже, я успешно расширил свою и без того долгую функцию. Позже мы уточним это, но вот рабочий код в одном лице. Отметка правильного ответа JD.

    enabled_list = []
    for root, dirs, files in os.walk((start_folder)):
        # get all files in specified folder
        for file in files:
            # check only specific files
            if file.endswith("*.cnf"):
                # get full path to file
                file_full = ( os.path.join(root, file) )
                # check if file contains anything in ignore paths list
                if not any(ignore in str(file_full) for ignore in ignore_if_path_contains):
                    if debug:
                        print(file_full)
                    # ensure file is readable
                    if CheckFilePermission(file_full, "R"):
                        file_full_read = open( (file_full), 'rb' )
                        # check if file contains any headers
                        if (re.search( r'\[.+\]', str(file_full_read.read()) )):
                            if debug:
                                print( "found string in file: "+(file_full) )
                            with open( (file_full), 'r' ) as rfile:
                            '''
                            1. open the file
                            2. read the lines
                            3. for each line see if its a header line
                            4. if so check if previous cur_line was valid
                                if so add it to the list since it survived til next header
                            5. otherwise set cur_line to current header found and move on
                            6. if disabled found, clear cur_line and move on
                            '''
                                cur_line = ""
                                for line in rfile.readlines():
                                    if not any(ignore in str(line) for ignore in ignore_if_section_name_contains):
                                        if ( re.search( r'\[.+\]', (line) ) ):
                                            if cur_line:
                                                enabled_list.append(cur_line)
                                                cur_line = ""
                                            if debug:
                                                print( "found string in line: "+(line) )
                                            cur_line = line
                                        elif re.search(r'disabled *= *(true|1)', line):
                                            cur_line = ""
                                            continue
                                # check if cur line valid at EOF since no more loops left
                                if cur_line:
                                    enabled_list.append(cur_line)
                                    cur_line = ""
    enabled_list = list(dict.fromkeys(enabled_list))
    return(enabled_list)

1 Ответ

0 голосов
/ 10 июля 2020

Я бы создал отдельную функцию для обработки строк из: rfile.readlines()

def find_enabled(lines):
  name = None
  for line in lines:
    if re.search(r'\[.+\]', line):
      name = line
      # no break, keep going to check if it's enabled
    
    elif re.earch(r'disabled *= *(true|1)', line):
      # found disabled, return None
      return None

  # if we made it this far then we found it with no disabled found or not found at all
  return name

По аналогичному примечанию / о ремонтопригодности я бы разбил все это на крошечные маленькие функции, которые делают одно и то же только для того, чтобы сделать его более читабельным, а такие изменения намного проще.

Для нескольких блоков в одном файле идея одна и та же, просто нужно отслеживать последний найденный вами и сохранять его, если у нас нет ' t видел заблокированный блок

def find_enabled(lines):
    names = []
    last = None
    for line in lines:
        if re.search(r'\[.*\]', line):
            if last:
                names.append(last)
            last = line

        elif re.search(r'disabled *= *(true|1)', line):
            last = None

    if last:
        names.append(last)

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