【问题标题】:Python: Make List of Matching Patterns for Subprocess Call to pcregrep multilinePython:为对 pcregrep 多行的子进程调用制作匹配模式列表
【发布时间】:2017-03-21 22:00:25
【问题描述】:

TLDR:有没有一种简洁的方法来为 subprocess.check_output('pcregrep', '-M', '-e', pattern, file) 制作条目列表?

我正在使用 python 的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() 分隔符。

有没有一种简洁的方法来创建匹配的多行模式列表?

【问题讨论】:

  • 我没有看到任何使用外部工具的理由,你为什么不使用 re 模块?
  • 公平点,我只是有更多使用 grep、pcgrep 等的经验,而不是使用 re 到 grep 文件。我还认为 pcregrep 可能会对此进行更多优化,并且性能将(最终)成为一个因素。
  • 停止梦想表演,并尝试使用语言正则表达式引擎,看看它是否可以完成这项工作,以及执行此操作所需的时间是否可以满足您的需求。之后,并且仅在之后(当您尽一切可能完善您的模式或找到其他语言方式时),尝试使用外部工具。
  • 明白了。我通常喜欢在刚开始时考虑性能,所以我可能要做的工作更少,但你说得对,正则表达式机器可能绰绰有余。

标签: python python-2.7 subprocess pcregrep


【解决方案1】:

根据 Casimir et Hippolyte 的评论和非常有用的帖子 How do I re.search or re.match on a whole file without reading it all into memory?,我在文件中使用 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)

创建所需的列表。

【讨论】:

    【解决方案2】:

    不要那样做。如果由于某种原因无法使用 Python 正则表达式模块,请使用 Python bindings for pcre

    【讨论】:

    • 请注意,大多数时候,当您感到被 re 模块束缚时,您可以使用正则表达式模块:pypi.python.org/pypi/regex,它拥有您梦想的所有功能(包括大部分 pcre 功能) .
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-24
    • 1970-01-01
    • 2011-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-01
    相关资源
    最近更新 更多