Как читать определенные строки после того, как вы найдете какой-то текст в Python?

Способ иметь отдельную реализацию выглядит следующим образом.

//inner_foo.h

template <typename T>
struct Foo
{
    void doSomething(T param);
};


//foo.tpp
#include "inner_foo.h"
template <typename T>
void Foo<T>::doSomething(T param)
{
    //implementation
}


//foo.h
#include <foo.tpp>

//main.cpp
#include <foo.h>

inner_foo имеет форвардные объявления. foo.tpp имеет реализацию и включает inner_foo.h; и foo.h будет иметь только одну строку, чтобы включить foo.tpp.

Во время компиляции содержимое foo.h копируется в foo.tpp, а затем весь файл копируется в foo.h после который он компилирует. Таким образом, ограничений нет, и именование согласовано в обмен на один дополнительный файл.

Я делаю это, потому что статические анализаторы для кода разбиваются, когда он не видит передовые объявления класса в * .tpp. Это раздражает при написании кода в любой среде IDE или с помощью YouCompleteMe или других.

1
задан user2954167 13 July 2018 в 17:23
поделиться

4 ответа

Я обычно использую цикл while для чего-то подобного, с петлей for, вложенной внутри:

with open(filename) as f_in:
  while True:
    line = f_in.readline().strip()
    if not line:
      break
    if line == "text":
      data = [f_in.readline().strip() for i in range(15) if i in [2, 11, 13, 14]]

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

Обратите внимание, что этот код будет лишать ведущие и конечные пробелы из линии. Если вы хотите удалить только пробелы, вы можете использовать rstrip(). Если вы хотите вообще не менять строку, вы можете попробовать совпадение с префиксом startswith() или просто включить символ новой строки в ваше состояние.

0
ответ дан argx 17 August 2018 в 12:20
поделиться
  • 1
    как насчет перекрывающихся сегментов? – lenik 13 July 2018 в 17:36
  • 2
    Спасибо, отредактирован для решения проблемы перекрывающихся сегментов. – argx 13 July 2018 в 17:45
  • 3
    Это очень элегантно и точно, что я искал. Способ определения data облегчает получение информации из строк чтения, которые мне нужны. Спасибо огромное! – user2954167 13 July 2018 в 17:55

Я бы рекомендовал следующее решение

with open('file') as f:
    lines = f.readlines()

lines = list(filter(lambda x: 'text' in x, lines))
lines_for_header = [3,12,13,14,15]
head = lines[i for i in lines_for_header]
print(head)
-2
ответ дан modesitt 17 August 2018 в 12:20
поделиться
  • 1
    вам нужно сначала найти text, затем прочитать строки – lenik 13 July 2018 в 17:34
  • 2
    не читайте весь файл в памяти. Заголовок может быть в начале нескольких терабайтных файлов. – rth 13 July 2018 в 17:37
  • 3
    не читал его требования. Я просто добавил простой фильтр. Это определенно менее уродливо, чем все эти петли и условные обозначения – modesitt 13 July 2018 в 17:37
  • 4
    @rth, что может быть очень преждевременной оптимизацией – modesitt 13 July 2018 в 17:37

Попробуйте построить цикл и подсчитать ваши строки. Что-то связать это

rl = []
with opne("your_file") as fd:
  cnt = 25 #let's start outside required line number after text
  for l in fd.readlines():
     cnt += 1
     if "text" in l: # "text" in your line
       cnt = 0       # reset counter
     elif cnt in [3,12,13,14,15]: # if counter is one of lines you want
       rl.append(l)               # record them
print rl
-1
ответ дан rth 17 August 2018 в 12:20
поделиться

Если вы уверены, что не будет никаких перекрывающихся разделов, вы можете использовать что-то вроде:

lineno = 0
needed = [3, 12, 14, 15] # This may need adjusting to allow for lineno running from 1
found_at = None
for line in open('filename.txt').readlines():  # This will read blocks of lines for speed
    lineno += 1  # Human readable line numbers
    if found_at:
        if (lineno - found_at) in needed:
            print(lineno, line)
        elif (lineno - found_at) > max(needed):
            found_at = None
    elif text in line:
        found_at = lineno

Вы также можете использовать сложное регулярное выражение, но, вероятно, не стоит времени построить один и будет намного менее ясным.

0
ответ дан Steve Barnes 17 August 2018 в 12:20
поделиться
Другие вопросы по тегам:

Похожие вопросы: