Python多行模式匹配
我试图通过python使用shell命令匹配多行模式 我可以使用shell命令进行匹配,但无法通过Python subprocess.call或os.system模块传递此命令 我的文件如下所示:Python多行模式匹配,python,subprocess,pcregrep,Python,Subprocess,Pcregrep,我试图通过python使用shell命令匹配多行模式 我可以使用shell命令进行匹配,但无法通过Python subprocess.call或os.system模块传递此命令 我的文件如下所示: (CELL (CELLTYPE "NAND_2X1") (INSTANCE U2) (DELAY (ABSOLUTE (IOPATH A1 ZN (0.02700::0.02700) (0.01012::0.01012)) (IOPATH A2 ZN (0.0294
(CELL
(CELLTYPE "NAND_2X1")
(INSTANCE U2)
(DELAY
(ABSOLUTE
(IOPATH A1 ZN (0.02700::0.02700) (0.01012::0.01012))
(IOPATH A2 ZN (0.02944::0.02944) (0.00930::0.00930))
)
)
)
不,我正在尝试提取以下内容:
(INSTANCE U2)
(DELAY
(ABSOLUTE
(IOPATH A1 ZN (0.02700::0.02700) (0.01012::0.01012))
(IOPATH A2 ZN (0.02944::0.02944) (0.00930::0.00930))
)
)
使用此正则表达式:
pcregrep -M -n 'INSTANCE U2((?!^\)).*\n)+' sdf/c1_syn_buf2.sdf
其中U2是搜索字符串,sdf/c1_syn_buf2.sdf是文件名
在Python中,我定义了一个函数,我将向该函数传递搜索字符串和文件名,因为我必须多次执行此操作
我无法使用以下命令作为shell命令成功执行此命令:
>>>b = subprocess.call(['pcregrep','-M','-n','INSTANCE '+arg, '\)((?!^\).*\n)+ '+file ])
pcregrep: Failed to open \)((?!^\).*
)+ /home/sanjay/thesis/code/sdf/c7552_syn_buf0.sdf: No such file or directory
当我实际输入参数名(本例中为U2)和文件名时,我能够获得所需的输出
编辑
如果pcregrep不够友好,以下是awk命令:
awk '/INSTANCE U2/,/^)\n?/' sdf/c1_syn_buf2.sdf
返回相同的值
有人能帮我吗?只需查看原始命令行,并将调用的格式设置为每行一个参数,是否应该是这样
b = subprocess.call(
['pcregrep',
'-M',
'-n',
'INSTANCE {}\)((?!^\)).*\n)+ '.format(arg),
file ])
我对括号和反斜杠不是很确定。这些在正则表达式中总是有点棘手。您可能需要对它们稍加修改才能得到您想要的内容(查看python文档中的r''正则表达式字符串类型)看起来我需要使用格式说明符
%s
当我使用:
b = subprocess.check_output("pcregrep -M -n 'INSTANCE '%s'((?!^\)).*\n)+' {} ".format(file) %arg,shell=True)
这样,我就得到了变量b
我使用%s传递参数,使用
{}.format
方法传递文件名来运行shell命令:
$ pcregrep -M -n 'INSTANCE U2((?!^\)).*\n)+' sdf/c1_syn_buf2.sdf
在Python中:
from subprocess import check_output as qx
output = qx(['pcregrep', '-M', '-n', r'INSTANCE {}((?!^\)).*\n)+'.format(arg),
path_to_sdf])
import re
from mmap import ACCESS_READ, mmap
with open(path_to_sdf) as f, mmap(f.fileno(), 0, access=ACCESS_READ) as s:
# arg = re.escape(arg) # call it if you want to match arg verbatim
output = re.findall(r'INSTANCE {}((?!^\)).*\n)+'.format(arg).encode(), s,
flags=re.DOTALL | re.MULTILINE)
- 使用
literal或将所有反斜杠加倍r'
- 将每个shell参数作为单独的列表项传递
pcregrep
,您可以用Python搜索该文件:
from subprocess import check_output as qx
output = qx(['pcregrep', '-M', '-n', r'INSTANCE {}((?!^\)).*\n)+'.format(arg),
path_to_sdf])
import re
from mmap import ACCESS_READ, mmap
with open(path_to_sdf) as f, mmap(f.fileno(), 0, access=ACCESS_READ) as s:
# arg = re.escape(arg) # call it if you want to match arg verbatim
output = re.findall(r'INSTANCE {}((?!^\)).*\n)+'.format(arg).encode(), s,
flags=re.DOTALL | re.MULTILINE)
mmap
用于容纳内存中不适合的文件。它在Windows上也可能运行得更快。我想您只是有一个打字错误:.*\n)+'+文件它可能应该是.*\n)+',用逗号而不是逗号的文件plus@rkh这不是打字错误,括号中的内容基本上是说(.*\n)+
,我添加了(?!\))
表示只有在遇到以开头的行时才需要进行匹配。
分隔arg from')的逗号也应该是+,我认为,因此列表中的元素是子流程callI的单个参数,我没有得到这个参数,我想在搜索字符串中输入arg
。格式行将在搜索字符串中输入arg。如果arg设置为“Hello”,那么“INSTANCE{}”(?!^)。*\n)+。format(arg)等于“INSTANCE Hello”(?!^)。*\n)+”(加上或减去一些反斜杠)嗯……我实际上刚刚尝试过,现在pcregremp报告错误:>b=subprocess.call(['pcregremp','-M','-n','INSTANCE{}\(?!^\).\n')。format(arg),file])pcregrep:命令行正则表达式中偏移量为25的错误:丢失)
我希望有一个简单的backtick或exec方法用于类似perl的Python!看看你原来的正则表达式,我想我在中间忘了一个额外的“”。我刚刚编辑过。希望反斜杠是正确的…您应该使用%
或.format
字符串格式。同时使用这两个命令看起来很难看。@Sebastian我对python相当陌生,因此使用的是Unix命令。.感谢mmap方法,它工作得非常好!感谢对qx的类似perl的方法