如何在python中解决这个正则表达式问题
我正在尝试生成一个python脚本,它应该逐行读取verilog代码,当它遇到“Inputsome_name;”时它应该匹配行和返回名称,这样我就可以计算我在verilog代码中定义的所有输入端口(verilog代码非常大)。 所以verilog代码是这样的如何在python中解决这个正则表达式问题,python,regex,python-3.x,verilog,Python,Regex,Python 3.x,Verilog,我正在尝试生成一个python脚本,它应该逐行读取verilog代码,当它遇到“Inputsome_name;”时它应该匹配行和返回名称,这样我就可以计算我在verilog代码中定义的所有输入端口(verilog代码非常大)。 所以verilog代码是这样的 module(a,b,c,d, vbg `ifdef USE_GOOD_PIN , vb, vc, vd, vg ..... some more input and outputs `endif ); input [7:0]
module(a,b,c,d, vbg
`ifdef USE_GOOD_PIN
, vb, vc, vd, vg ..... some more input and outputs
`endif
);
input [7:0] t_d;
input srd;
output comb;
output src;
inout [1:0] Iout;
output a_in;
output b_in;
input ff_parity;
我试图匹配的代码('input[7:0]t_d;'input srd;'等)是
同样,在“input”和“[]”以及“name”之间可以有一个或多个空格,因此如何使用python正则表达式精确地获得“t_d”或“srd”之类的名称
使用我输入的代码,我无法满足要求。您可以将变量空格与
\s*
(零个或多个空格)或\s+
(一个或多个空格)匹配,并且可以使用(…)
括号“捕获”文本
查看,您可以看到您将查找input
,后跟一个可选范围,后跟一个或多个标识符,这些标识符是。以下模式将从此类语句中捕获标识符列表:
r'^input\s+(?:\[[^\]]*\]\s+)?(.+);'
(?:\[[^\]]*\]\s+
部分将匹配可选范围语法(a[
,后跟非]
字符上的任何数字,后跟]
),而不捕获它。有关在线演示,请参阅
由于标识符总是以空格分隔,因此可以使用str.split()
将捕获的值转换为Python列表
您不需要将文件读入内存或使用range
。直接在文件上循环。在处理单个行时,不需要使用re.M
。我也会删除re.I
,因为Verilog是区分大小写的<代码>输入与输入
不同:
with open(r'D:/pyfile/verilog.v') as file:
for line in file:
match = re.search(r'^input\s+(?:\[[^\]]*\]\s+)?(.+);', line)
if match:
identifiers = match.group(1).split()
print(*identifiers)
使用您的示例演示:
>>> import re
>>> from io import StringIO
>>> sample = '''\
... module(a,b,c,d, vbg
... `ifdef USE_GOOD_PIN
... , vb, vc, vd, vg ..... some more input and outputs
... `endif
... );
...
... input [7:0] t_d;
... input srd;
... output comb;
... output src;
... inout [1:0] Iout;
... output a_in;
... output b_in;
... input ff_parity;
... '''
>>> with StringIO(sample) as file:
... for line in file:
... match = re.search(r'^input\s+(?:\[[^\]]*\]\s+)?(.+);', line)
... if match:
... identifiers = match.group(1).split()
... print(*identifiers)
...
t_d
srd
ff_parity
您可以将变量空白与
\s*
(零个或多个空格)或\s+
(一个或多个空格)匹配,并且可以使用(…)
括号“捕获”文本
查看,您可以看到您将查找input
,后跟一个可选范围,后跟一个或多个标识符,这些标识符是。以下模式将从此类语句中捕获标识符列表:
r'^input\s+(?:\[[^\]]*\]\s+)?(.+);'
(?:\[[^\]]*\]\s+
部分将匹配可选范围语法(a[
,后跟非]
字符上的任何数字,后跟]
),而不捕获它。有关在线演示,请参阅
由于标识符总是以空格分隔,因此可以使用str.split()
将捕获的值转换为Python列表
您不需要将文件读入内存或使用range
。直接在文件上循环。在处理单个行时,不需要使用re.M
。我也会删除re.I
,因为Verilog是区分大小写的<代码>输入与输入
不同:
with open(r'D:/pyfile/verilog.v') as file:
for line in file:
match = re.search(r'^input\s+(?:\[[^\]]*\]\s+)?(.+);', line)
if match:
identifiers = match.group(1).split()
print(*identifiers)
使用您的示例演示:
>>> import re
>>> from io import StringIO
>>> sample = '''\
... module(a,b,c,d, vbg
... `ifdef USE_GOOD_PIN
... , vb, vc, vd, vg ..... some more input and outputs
... `endif
... );
...
... input [7:0] t_d;
... input srd;
... output comb;
... output src;
... inout [1:0] Iout;
... output a_in;
... output b_in;
... input ff_parity;
... '''
>>> with StringIO(sample) as file:
... for line in file:
... match = re.search(r'^input\s+(?:\[[^\]]*\]\s+)?(.+);', line)
... if match:
... identifiers = match.group(1).split()
... print(*identifiers)
...
t_d
srd
ff_parity
下面的代码更改应该可以做到这一点
match = re.match(r'input\s+(.*)\s*(.*)',lines[i], re.M|re.I)
if (match):
matches = list(match.groups())
if '' in matches:
matches.remove('')
print matches[-1]
else:
print 'nomatch'
“\s”字符序列与空白相匹配。是一个很好的正则表达式教程 下面的代码更改应该可以做到这一点
match = re.match(r'input\s+(.*)\s*(.*)',lines[i], re.M|re.I)
if (match):
matches = list(match.groups())
if '' in matches:
matches.remove('')
print matches[-1]
else:
print 'nomatch'
“\s”字符序列与空白相匹配。是一个很好的正则表达式教程 您只需将整个输入字符串转换为字符列表。由于它总是缺少一个空字符,因此会抛出
ValueError:list.remove(x):x不在list
@MartijnPieters:I已修复ValueError部分。谢谢。您仍然打印错误的输出。为什么使用列表(match.group())
match.group()
不是捕获的部分。另外,您总是捕获两个组,都使用*
。对于输入
行上的多个标识符,这绝对会给您错误的值。对于长线,回溯成本也将非常大。意味着使用match.groups()而不是match.group()。谢谢同意我的解决方案不适用于所有可能的verilog语法。您只需将整个输入字符串转换为字符列表。由于它总是缺少一个空字符,因此会抛出ValueError:list.remove(x):x不在list
@MartijnPieters:I已修复ValueError部分。谢谢。您仍然打印错误的输出。为什么使用列表(match.group())
match.group()
不是捕获的部分。另外,您总是捕获两个组,都使用*
。对于输入
行上的多个标识符,这绝对会给您错误的值。对于长线,回溯成本也将非常大。意味着使用match.groups()而不是match.group()。谢谢同意我的解决方案不适用于所有可能的verilog语法。