如何在python中解决这个正则表达式问题

如何在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]

我正在尝试生成一个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] 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语法。