Как работать с этой проблемой регулярных выражений в Python - PullRequest
0 голосов
/ 25 ноября 2018

Я пытаюсь сгенерировать скрипт на python, который должен построчно читать код verilog и когда он встречает 'input some_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;' и т. д.), равен

 import re
 file = open(r'D:/pyfile/verilog.v' ,"r")
 lines = file.readlines()
 print(len(lines))
 for i in range(0,len(lines)):
      print(lines[i],end = '')
      match = re.match(r'input (.*)',lines[i], re.M|re.I)
      if (match):
            print(match.group(1))
      else:
            print("nomatch")

снова может быть один или несколько пробелов между 'input' и '[]' и 'name', так как точно получить имя типа 't_d' или 'srd', используя регулярные выражения python.

сКод, который я ввел, не соответствует требованию.

Ответы [ 2 ]

0 голосов
/ 25 ноября 2018

Следующие изменения кода должны помочь.

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' соответствует пробелу. Этот является хорошим руководством для регулярных выражений.

0 голосов
/ 25 ноября 2018

Вы можете сопоставить переменные пробелы с \s* (ноль или более пробелов) или \s+ (один или несколько пробелов), и вы можете «захватить» текст с помощью (...) скобок.

Просмотр это описание синтаксиса Verilog input , вы можете увидеть, что вы ищете input, за которым следует необязательный диапазон, за которым следуют 1 или более идентификаторов, которые ограничены пробелами .Следующий шаблон будет захватывать список идентификаторов из такого оператора:

r'^input\s+(?:\[[^\]]*\]\s+)?(.+);'

Часть (?:\[[^\]]*\]\s+)? будет соответствовать необязательному синтаксису диапазона (a [, за которым следует любое числона не ] символах, за которыми следует ]), без захвата.См. https://regex101.com/r/cT0Q0X/1 для онлайн-демонстрации.

Поскольку идентификаторы всегда разделены пробелами, вы можете затем использовать str.split(), чтобы превратить это захваченное значение в список Python.

Youне нужно читать файл в память или использовать range.Просто зациклите файл напрямую.И вам не нужно использовать re.M, так как вы обрабатываете отдельные строки.Также я бы опустил re.I, так как Verilog чувствителен к регистру;INPUT - это не то же самое, что input:

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
...