Извлечение указанного c текста между строками - PullRequest
0 голосов
/ 25 апреля 2020

Я пытаюсь извлечь указанные c строки из файла .txt, соответствующих 7 конкретным устройствам (0-6), а затем оперировать этими данными.

Вот пример:

Из очень большого файла я извлекаю событие (здесь 169139), которое содержит информацию от 6 из 7 устройств (здесь всего 1,2,3, 4,5,6, потому что устройство 0 не имеет данных). Для каждого такого события я априори не знаю, сколько устройств будет выдавать активное в качестве своего выхода. Это может быть все, это может быть ни одно, или это может быть несколько.

=== 169139 ===
Start: 4.80374e+19
End:   4.80374e+19
--- 1 ---
Pix 9, 66
--- 2 ---
Pix 11, 31
Pix 12, 31
--- 3 ---
Pix 17, 53
Pix 16, 53
Pix 16, 54
--- 4 ---
Pix 44, 64
--- 5 ---
Pix 49, 133
Pix 48, 133
--- 6 ---
Pix 109, 143
Pix 108, 143
Pix 108, 144 
Pix 109, 144 

События легко повторяются, и я могу выбрать всю информацию на экране до следующей (здесь, следующая строка из .txt будет === 169140 ===).

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

def start_stop_plane (list, dev):
    start_reading = [i for i in range(len(list)) if list[i] == "--- " + str(dev) + " ---"][0]
    stop_reading = [i for i in range(len(list)) if list[i] == "--- " + str(int(dev)+1) + " ---"][0]
    return list[start_reading:stop_reading]

Здесь, list - первый комментарий кода (полное событие). Это список, созданный аналогично приведенному выше коду, заменяющий --- на === вхождений строк (ie, флаг между событиями).

Моя проблема: это работает для всего от 0 до 5. Для 6 он падает, потому что нет int(dev)+1. Я попытался вставить or в stop_reading, чтобы идентифицировать вхождение ===, но оно не сработало.

В этом случае, Как я могу сообщить об окончании списка и убедиться, что я не не потеряете какое-либо устройство?

Ответы [ 2 ]

1 голос
/ 25 апреля 2020

Вы можете использовать строку Индекс

Код

def start_stop_dev(lst, dev):
    " Assume you meant dev rather than plane "
    try:
      start_reading = lst.index("--- " + str(dev) + " ---")
    except:
      return ""   # No device

    try:
      stop_reading = lst.index("--- " + str(dev+1) + " ---") - 1
    except:
      stop_reading = len(lst)

    if start_reading:
        return lst[start_reading:stop_reading]
    else:
      return None  # not really possible since return "" earlier

Тест

lst= """=== 169139 ===
Start: 4.80374e+19
End:   4.80374e+19
--- 1 ---
Pix 9, 66
--- 2 ---
Pix 11, 31
Pix 12, 31
--- 3 ---
Pix 17, 53
Pix 16, 53
Pix 16, 54
--- 4 ---
Pix 44, 64
--- 5 ---
Pix 49, 133
Pix 48, 133
--- 6 ---
Pix 109, 143
Pix 108, 143
Pix 108, 144 
Pix 109, 144"""

# Retrieve and print data for each device
print('----------------Individual Device String Info-------------')
for dev in range(7):
  print(f'device {dev}\n{start_stop_dev(lst, dev)}')

print('----------------Splits of String Info----------------------')
for dev in range(7):
  dev_lst = start_stop_dev(lst,dev).split("\n")
  print(f'dev {dev}: {dev_lst}')

Вывод ---------------- Информация об отдельных строках устройства -------------

device 0

device 1
--- 1 ---
Pix 9, 66
device 2
--- 2 ---
Pix 11, 31
Pix 12, 31
device 3
--- 3 ---
Pix 17, 53
Pix 16, 53
Pix 16, 54
device 4
--- 4 ---
Pix 44, 64
device 5
--- 5 ---
Pix 49, 133
Pix 48, 133
device 6
--- 6 ---
Pix 109, 143
Pix 108, 143
Pix 108, 144 
Pix 109, 144
----------------Splits of String Info----------------------
dev 0: ['']
dev 1: ['--- 1 ---', 'Pix 9, 66']
dev 2: ['--- 2 ---', 'Pix 11, 31', 'Pix 12, 31']
dev 3: ['--- 3 ---', 'Pix 17, 53', 'Pix 16, 53', 'Pix 16, 54']
dev 4: ['--- 4 ---', 'Pix 44, 64']
dev 5: ['--- 5 ---', 'Pix 49, 133', 'Pix 48, 133']
dev 6: ['--- 6 ---', 'Pix 109, 143', 'Pix 108, 143', 'Pix 108, 144 ', 'Pix 109, 144']
1 голос
/ 25 апреля 2020

Вы должны подготовить маркер "--- plane ---" и позволить python найти его для вас, используя основные функции c, такие как in и .index.

. подмножество строк данных до следующего маркера, вы можете использовать takewhile из itertools:

data="""=== 169139 ===
Start: 4.80374e+19
End:   4.80374e+19
--- 1 ---
Pix 9, 66
--- 2 ---
Pix 11, 31
Pix 12, 31
--- 3 ---
Pix 17, 53
Pix 16, 53
Pix 16, 54
--- 4 ---
Pix 44, 64
--- 5 ---
Pix 49, 133
Pix 48, 133
--- 6 ---
Pix 109, 143
Pix 108, 143
Pix 108, 144 
Pix 109, 144""".split("\n")

from itertools import takewhile
def planeData(data,plane):
    marker = f"--- {plane} ---"
    if marker not in data: return []
    start = data.index(marker)+1
    return list(takewhile(lambda d:not d.startswith("---"),data[start:]))

вывод:

for line in planeData(data,0): print(line)
# nothing printed

for line in planeData(data,5): print(line)
# Pix 49, 133
# Pix 48, 133

for line in planeData(data,6): print(line)
# Pix 49, 133
# Pix 48, 133
# Pix 109, 143
# Pix 108, 143
# Pix 108, 144 
# Pix 109, 144
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...