Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[3.15.219.217] |
|
Сообщ.
#1
,
|
|
|
Есть файл-шаблон
Что-то &&1 Что-то_ещё <br>&&2 eщё_что-нибудь и есть файл сданными &&1=значение_1<br>&&2=значение_2 В резельтате должно получиться такое Что-то значение_1 Что-то_ещё <br>значение_2 eщё_что-нибудь Я эту проблему решил используя регулярные выражения для замены (s///) Но по-моему это весьма неоптимально. Есть ли в перле что-нить как раз для таких случаев? |
Сообщ.
#2
,
|
|
|
именно регулярные выражения для этого лучше всего и подходят.
|
Сообщ.
#3
,
|
|
|
Регулярные выражения для такой задачи перебор, наверняка в Perl есть функция а-ля strreplace, поиши доки на citforum.ru.
|
Сообщ.
#4
,
|
|
|
Что-то типа:
Читаешь файл 1 text1<br>2 text2<br>..........<br>n textn <br>local\%hash;<br>open F,"<$fname";<br>#flock F,4;<br>while(<F>)<br>{<br> $hash{$1}=$2 if /^(\d+?)\s+(.+?)[\r\n]*$/o;<br>}<br>#flock F,8;<br>close F; Открываешь другой, куда вставить и вставляешь: <br>local$frm=qr'&&(\d+)';<br>open F,"$another_fname";<br>#flock F,4;<br>while(<F>)<br>{<br> s/$frm/$hash{$1}/gos;<br> print;<br>}<br>#flock F,8;<br>close F;<br> |
Сообщ.
#5
,
|
|
|
А вообще вот тебе простенький парсер.
Назови его "Files.pm": #####################################################################<br>package Files;<br>######################################################################<br>sub readf<br>{<br> foreach(@_)<br> {<br> next if /[^\w\d\/\.]+/o||!-f($_);<br><br> my $fh;<br> open $fh,"<$_";<br> #flock $fh,4;<br> print <$fh>;<br> #flock $fh,8;<br> close $fh;<br> }<br> return 1;<br>}<br><br>sub preFormat<br>{<br> sub pre<br> {<br> my @r;<br> push @r,&fmt($_) foreach split ',',$_[0];<br> +@r;<br> }<br> sub fmt<br> {<br> my($res,$pack,@oth);<br> my $del='::';<br> my @word=split(/$del/o,shift,2);<br> if($word[1])<br> {<br> $pack=shift @word;<br> }<br> else<br> {<br> $pack='main';<br> }<br> $pack.=$del;<br> @oth=reverse split /\-/o,shift(@word);<br> $res=shift @oth;<br> if(@oth)<br> {<br> foreach(@oth)<br> {<br> $_=substr $_,1 unless index $_,'$';<br> $res=${$pack.$_}{$res};<br> }<br> return $res;<br> }<br> else<br> {<br> return ${$pack.substr($res,1)};<br> }<br> }<br> sub mk<br> {<br> my($c,$f)=@_;<br> return &readf($f) if $c eq 'inc';<br> }<br> sub textf<br> {<br> my @fval;<br> my $fstr=shift;<br> foreach(split /~/o,shift)<br> {<br> if(index $_,'@')<br> {<br> push @fval,$_;<br> }<br> else<br> {<br> push @fval,@{substr $_,1};<br> }<br> }<br> printf $fstr,@fval;<br> return @fval;<br> }<br> sub follow<br> {<br> my($func,@arg)=split(/\-\=\-/o,shift);<br> return &{$func}(@arg);<br> }<br> my($a,$join);<br> my($file)=shift;<br> my$fh;<br> open$fh,$file;<br> #flock$fh,4;<br> loop:while(<$fh>)<br> {<br> if(substr($_,0,1) eq '`')<br> {<br> my $str=undef;<br> while(<$fh>)<br> {<br> if(substr($_,0,1) eq '`')<br> {<br> eval $str;<br> print "<!--error eval-->\n" if $@;<br> goto loop;<br> }<br> else<br> {<br> $str.=$_;<br> }<br> }<br> }<br> s/{{([^{}]*)}}/$join=$1;next;/eo;<br> s/{([^{}]+)}/join $join,&pre($1)/geo;<br> s/\\n/\n/go;<br> s/\\t/\t/gos;<br> s/\\r/\r/gos;<br> if(/^\-\-\=(.+)\=\-\-/os)<br> {<br> print unless &follow($1);<br> }<br> else<br> {<br> print;<br> }<br> }<br> #flock$fh,8;<br> close$fh;<br>}<br><br>1; Использование: use Files;<br>local$lfh=select STDOUT;<br>&Files::preFormat($filename);<br>select$lfh; Выдёргивает имена переменных из форматируемого файла и вставляет их значение: {main::$show} - эквивалент $main::show;<br>{::$show} - эквивалент $::show<br>{ARG-SHOW} - эквивалент $ARG{SHOW}<br>{ARG-SHOW-SHOW} - эквивалент $ARG->{SHOW}->{SHOW}<br>"--=readf-=-filename=--" - вставить файло |