Python: создание списка подходящих шаблонов для вызова подпроцесса, чтобы pcregrep multiline

TLDR: есть ли чистый способ сделать список записей для subprocess.check_output('pcregrep', '-M', '-e', pattern, file)?

Я использую питона subprocess.check_output() звонить pcregrep -M, Обычно я бы отделил результаты, позвонив splitlines() но так как я ищу многострочный шаблон, это не сработает. У меня проблемы с поиском чистого способа создания списка подходящих шаблонов, где каждая запись в списке является индивидуальным подходящим шаблоном.

Вот простой пример файла, который я pcgrep'ing

module test_module(
    input wire in0,
    input wire in1,
    input wire in2,
    input wire cond,
    input wire cond2,
    output wire out0,
    output wire out1
);

assign out0 = (in0 & in1 & in2);
assign out1 = cond1 ? in1 & in2 :
              cond2 ? in1 || in2 :
              in0;

Вот (некоторые из) мой код Python

#!/usr/bin/env python
import subprocess, re

output_str = subprocess.check_output(['pcregrep', '-M', '-e',"^\s*assign\\s+\\bout0\\b[^;]+;", 
                                     "/home/<username>/pcregrep_file.sv"]).split(';')

# Print out the matches
for idx, line in enumerate(output_str):
    print "output_str[%d] = %s" % (idx, line)

# Clear out the whitespace list entries                           
output_str = [line for line in output_str if re.match(\S+, line)]

Вот вывод

output_str[0] = 
assign out0 = in0 & in1 & in2
output_str[1] = 
assign out1 = cond1 ? in1 & in2 :
              cond2 ? in1 || in2 :
              in0
output_str[2] = 

Было бы хорошо, если бы я мог сделать что-то вроде

output_list = subprocess.check_output('pcregrep', -M, -e, <pattern>, <file>).split(<multiline_delimiter>)

без создания мусора для очистки (записи списка пробелов) или даже без разделителя split() на это не зависит от шаблона.

Есть ли чистый способ создать список подходящих многострочных шаблонов?

2 ответа

За комментарий Казимира и Ипполита, а также очень полезный пост: Как мне заново исследовать или заново сопоставлять весь файл, не считывая все это в память? Я читаю в файле используя re вместо внешнего звонка в pcregrep и использовал re.findall(pattern, file, re.MULTILINE)

Полное решение (которое лишь слегка изменяет ссылочный пост)

#!/usr/bin/env python
import re, mmap

filename = "/home/<username>/pcregrep_file.sv"
with open(filename, 'r+') as f:
    data = mmap.mmap(f.fileno(), 0)
    output_str = re.findall(r'^\s*assign\s+\bct_ela\b[^;]+;', data, re.MULTILINE)
    for i, l in enumerate(output_str):
    print "output_str[%d] = '%s'" % (i,l)

который создает желаемый список.

Не делай этого. Если по какой-то причине вы не можете использовать модуль регулярных выражений Python, просто используйте привязки Python для pcre.

Другие вопросы по тегам