Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Perl: Общие вопросы > Одновременно поиск и замена


Автор: s_a_s_h_a 16.3.2005, 14:07
Вопрос. Можно ли сделать следующее и если да, то как это лучше сделать. В тексте встречаются последовательности символов:

.cgi?id=111
.cgi?id=121
.cgi?id=21

надо найти и сохранить в массиве числа, а эти последовательности заменить в тексте на

#pic_1#
#pic_2#
#pic_3#

Автор: chaos 16.3.2005, 14:16
вот небольшой пример
Код

$str="blablabla.cgi?id=111";
if ($str =~ /(.+\.cgi\?id=)(\d+)/) {
  $mas[$counter++] = $2;
  $temp="#pic_${2}#";
  $str ~= s/(.+\.cgi\?id=)/$temp/;
}

Может не работать smile тк не проверял, перла нет

Автор: s_a_s_h_a 16.3.2005, 14:23
В тексте не одна последовательность вида .cgi?id=M (M - число), а несколько. И важно, что в #pic_N# N принимает значения 1, 2, 3, ...



Автор: korob2001 16.3.2005, 20:55
Только вот я не понял, где хранится текст???? Вот припмер с массивом строк, если нужно работать с файлами и не сможешь подправить сам, дай знать:
Код

#!/usr/bin/perl -w
use strict;
my $i = 0;
my @arr;
my @strs = qw( fdfddsfsddv.cgi?id=814fdfdfdfdfdf.cgi?id=102fdfdfdfdf.cgi?id=21
               fdfddsfsddv.cgi?id=190fdfdfdfdfdf.cgi?id=511fdfdfdfdf.cgi?id=47
               fdfddsfsddv.cgi?id=214fdfdfdfdfdf.cgi?id=707fdfdfdfdf.cgi?id=82
               fdfddsfsddv.cgi?id=234fdfdfdfdfdf.cgi?id=331fdfdfdfdf.cgi?id=11 );
# Вот так выглядит наш массив до обработки
print join("\n", @strs), "\n\n";
print "=" x 70, "\n\n";

# Обрабатываем массив
foreach my $str ( @strs ) {
     push( @arr, $1 ) while $str =~ s/\.cgi\?id=(\d+)/"#pic_" . $i++ . "#"/ei;
}

# Покажем массив после обработки
print join("\n", @strs), "\n";
print "-" x 70, "\n";
print "\@arr = " . join(", ", @arr), "\n";

print "\n\n";
print "=" x 70, "\n\n";

# А вот обратное преобразование
foreach my $str ( @strs ) {
     $str =~ s/\#pic_(\d+)\#/.cgi?id=$arr[$1]/ig;
}
# Покажем массив после обратной обработки
print join("\n", @strs), "\n";

Здесь показана замена как в одну сторону, так и в другую. ;)))))

Удачи.

Автор: Kiber_rat 16.3.2005, 21:23
Если я правильно понял задачу, то надо все числа после cgi?id= сохранить в массив, а сами .cgi?id=М заменить на #pic_[array index]#?
Если вопрос в этом то можно сделать так:
Код

#!/usr/bin/perl -w
use strict;
my $i=1;
my @arr;
my $txt= <<EOF;
Some text here cgi?id=111 some text here cgi?id=112
Some text here cgi?id=121 some text here cgi?id=122
Some text here cgi?id=21 some text here cgi?id=211
EOF
$arr[$i++-1]=$1  while $txt=~s!cgi\?id=(\d+)!#pic_$i#!i;
print $txt;
print "$_\n" for @arr;

Автор: korob2001 16.3.2005, 22:18
Kiber_rat - со стёком Perl работает быстрее, чем с индексами.

Автор: Kiber_rat 16.3.2005, 23:30
Ок smile Если это критичное по скорости приложение тогда так:
Код

push @arr, $1  while $txt=~s!cgi\?id=(\d+)!#pic_$i++#!i;

Автор: korob2001 17.3.2005, 06:27
Kiber_rat - какую роль играет переменная $i?????
Код

push @arr, $1  while $txt=~s!cgi\?id=(\d+)!#pic_$i#!i;


Автор: s_a_s_h_a 17.3.2005, 09:24
korob2001, спасибо. То что нужно. Инфа хранится в строковой переменной, сам справился.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)