【问题标题】:perl multiple regex match over multiple linesperl 多个正则表达式匹配多行
【发布时间】:2019-03-08 21:29:09
【问题描述】:

我正在努力尝试在文本文件的一组行中捕获多个匹配项。

数据有很多形式,比如

AO22_X1N_A9PP96CTS_C24 SYN_INC_187 ( .A0 ( test_so6 ) , .A1 ( n2218 ) , .B0 (U_PAUSEdata_ff_int_28_),.B1(n2),.Y(n2597));

NAND3_X1R_A9PP96CTUL_C16 SYN_INC_154 ( .A ( n1563 ) , .B(U_PAUSEwcnt),.C(n1640),.Y(n1467));

第一部分是一个名字。以后可能想要 tat 但现在我对端口 ex .A (net) 感兴趣 理想情况下,我想捕获所有输入网络名称(具有 A、B、C、D 等的网络名称)和单个输出 .Y(网络)

最终我想将它们存储到一个散列中,其中输出网络是键,数据是输入数组的引用,但现在我只是想捕获所有输入网络。

这就是我目前正在使用的东西

open (FILE, "<maca") or die("Can not open $file");
  while (defined(my $cur_line = <FILE>)) {

    if ($cur_line =~ m/[A-Z].*?\.[A-C]\d* \( (.*?) \).*?;/mg) { 
      print "THIS gate $cur_line $1 $2 $3\n";  
      }
  }

我正在尝试这个显示

这个门 NAND3_X1R_A9PP96CTUL_C16 SYN_INC_154 ( .A ( n1563 ) , .B(U_PAUSEwcnt),.C(n1640),.Y(n1467));

n1563 U_PAUSEwcnt n1640

但我明白了。其实我不关心第一行只是第二行。第一个用于调试。我认为 m 会搜索多行,而 g 会全局匹配多行字符串。我错过了什么

这个门.B(U_PAUSEwcnt),.C(n1640),.Y(n1467));

n1640

【问题讨论】:

  • 如果$cur_line 是单行,则不应使用多行正则表达式。尝试在没有 gm 修饰符的情况下匹配单个正则表达式中的三个字段
  • 使用 Verilog 解析器:metacpan.org/pod/Verilog-Perl
  • @Håkon Hægland 它实际上是一个文件中的多行。多行数据由 ; 终止
  • @toolic 我不知道有一个verilog解析器。感谢您指出了这一点。我会看看是否可以拉入综合网表。我可能会使用它,或者只是从模块中窃取代码。只想要一个简单的测试脚本。无需将整个设计拉入内存
  • vhier 辅助脚本可能是一个不错的起点。

标签: regex perl multilinestring


【解决方案1】:

如果我理解正确,您正在寻找这样的东西:

while ($data =~ /(\w+)\s*\((.+?)\)\s*;/gm) {
  my $line = $1;
  my $vals = $2;
  while ($vals =~ /\.(\w+)\s*\(\s*(\w+)\s*\)/g) {
    print "$line .. $1: $2.\n"
  }
}

我称变量为$data,因为它包含所有行——对吗? 我首先拆分行,捕获 ( .. ) 之间的字符串,然后提取键值对。看起来所有名称都是字母数字 +“_”,这很好地被 \w 捕获。

希望这有帮助吗?

【讨论】:

  • 哦,我现在明白了。我用了一段时间来阅读我的 $cur_line = ,然后使用与我详述的相同的 $cur_line 来进行正则表达式。我没有意识到我需要将全局多字符串匹配拉到一个变量中,然后用一段时间来遍历它。
  • 啊,我明白了 - 如果您发布完整代码会更容易;)没问题,您可以继续这样做(这是个好主意)。如果您将其与单独的行一起使用,上面的代码也将起作用。 (当然你可以使用if 并踢掉gm
  • 嗯,还没有和它打架。起初似乎可以工作,但与第一行不匹配。
  • 等待它的工作。好吧,我不得不在第一时间使用 gms 修饰符。 my $data = read_file("maca"); while ($data =~ m/([A-Z]\w+)\s+(\w+)\s+\((.+?)\)\s*;/mgs) { my $port_net_pairs = $3; while ($port_net_pairs =~ m/\.(\w+)\s+\(\s+(\w+)\s+\)/g) { my $port = $1; my $net = $2; print " $port : $net\n"; } } 现在我看到的唯一挑战是一些端口不仅仅是单词字符,还有方括号。例如 .B ( TX_cnt[0] )
  • woohoo 用while ($port_net_pairs =~ m/\.(\w+)\s+\(\s+([\w|\[|\]]+)\s+\)/g) {解决了这个问题
猜你喜欢
  • 1970-01-01
  • 2017-08-02
  • 1970-01-01
  • 1970-01-01
  • 2012-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多