2015-04-26 5 views
0

У меня есть небольшая проблема. Как я могу назначить диапазон в массив, как этот:Назначение диапазона массиву в Perl

входного файла: clktest.spf

* 
.GLOBAL vcc! vss! 
* 
.SUBCKT eclk_l_25h brg2eclk<1> brg2eclk<0> brg_cs_sel brg_out brg_stop cdivx<1> 
+ eclkout1<24> eclkout1<23> eclkout1<22> eclkout1<21> eclkout1<20> eclkout1<19> 
+ mc1_brg_dyn mc1_brg_outen mc1_brg_stop mc1_div2<1> mc1_div2<0> mc1_div3p5<1> 
+ mc1_div3p5<0> mc1_div_mux<3> mc1_div_mux<2> mc1_div_mux<1> mc1_div_mux<0> 
+ mc1_gsrn_dis<0> pclkt6_0 pclkt6_1 pclkt7_0 pclkt7_1 slip<1> slip<0> 
+ ulc_pclkgpll0<1> ulc_pclkgpll0<0> ulq_eclkcib<1> ulq_eclkcib<0> 
* 
*Net Section 
* 
*|GROUND_NET 0 
* 
*|NET eclkout3<48> 2.79056e-16 
*|P (eclkout3<48> X 0 54.8100 -985.6950) 
*|I (RXR0<16>#NEG RXR0<16> NEG X 0 54.2255 -985.6950) 
C1 RXR0<16>#NEG 0 5.03477e-17 
C2 eclkout3<48> 0 2.28708e-16 
Rk_6_1 eclkout3<48> RXR0<16>#NEG 0.110947 

выход (это должно быть сохранено значение в массиве)

.SUBCKT eclk_l_25h brg2eclk<1> brg2eclk<0> brg_cs_sel brg_out brg_stop cdivx<1> 
+ eclkout1<24> eclkout1<23> eclkout1<22> eclkout1<21> eclkout1<20> eclkout1<19> 
+ mc1_brg_dyn mc1_brg_outen mc1_brg_stop mc1_div2<1> mc1_div2<0> mc1_div3p5<1> 
+ mc1_div3p5<0> mc1_div_mux<3> mc1_div_mux<2> mc1_div_mux<1> mc1_div_mux<0> 
+ mc1_gsrn_dis<0> pclkt6_0 pclkt6_1 pclkt7_0 pclkt7_1 slip<1> slip<0> 
+ ulc_pclkgpll0<1> ulc_pclkgpll0<0> ulq_eclkcib<1> ulq_eclkcib<0> 
* 
*Net Section 

мой простой код:

#!/usr/bin/perl 
use strict; 
use warnings; 

my $input = "clktest.spf"; 

open INFILE, $input or die "Can't open $input" ; 

my @allports; 
while (<INFILE>){ 
    @allports = /\.SUBCKT/ ... /\*Net Section/ ; 
    print @allports; 
} 

Я выполняю правильную работу по назначению выбранного диапазона в массив? Если нет, то как я могу изменить этот код?

Спасибо за продвижение.

ответ

0

Петля while только дает одну строку в то время, так что вы не можете назначить все строки, которые вы хотите сразу. Вместо этого используйте push, чтобы развернуть массив по строкам.

Кроме того, вы должны использовать лексических файл обрабатывает как $in_fh (а не глобальные, как INFILE) с формой трехпараметрической open, и вы должны включать в себя $! переменных в die строки, так что вы знаете почему не удалось открыть.

Это как ваша программа должна выглядеть

#!/usr/bin/perl 
use strict; 
use warnings; 

my $input = 'clktest.spf'; 

open my $in_fh, '<', $input or die "Can't open $input: $!" ; 

my @allports; 

while (<$in_fh>) { 
    push @allports, $_ if /\.SUBCKT/ ... /\*Net Section/; 
} 

print @allports; 

Обратите внимание, что, если все, что вы хотите сделать, это распечатать выбранные строки из файла, вы можете забыть о массиве и заменить push @allports, $_ с print

0

<INFILE> внутри while будет читать файл по строкам, поэтому не подходящее место для применения регулярного выражения, которое должно охватывать более одной строки. Чтобы получить подстроку, самый простой способ - сначала соединить все эти строки. И только после этого вы примените свое регулярное выражение.

my $contents = ""; 
while (<INFILE>) { 
    $contents = $contents . $_; 
} 
$contents =~ s/.*(\.SUBCKT.*\*Net Section).*/$1/s; # remove unneeded part 

Пожалуйста, обратите внимание, что /s модификатор в последней части замещения линии. Это необходимо, потому что $contents содержит символы новой строки.

Чтобы получить подстроку в массив, просто использовать сплит my @allports = split("\n", $contents);

+0

Что означает '. */$ 1' в вашем регулярном выражении? И на ваш сплит-код, действительно ли это '¥ n'? – Meeyaw

+0

'. *' Before '(' и after') 'означает ненужную часть. '$ 1' будет содержать строку между ними. – tivn

+0

Спасибо за ответ. Для последующего наблюдения, как только я нашел раздел файла, я сделаю что-то вроде этого: $ contents = ~ tr /\\\\\\\\\; d; $ contents = ~ s/SUBCKT //; $ contents = ~ s/Net Section //; @ports = split ('', $ contents); Могу ли я сделать что-то меньшее, чем это? – Meeyaw

Смежные вопросы