Программирование > Регулярные выражения
Все, кроме выражения
Vladn:
metton
Предлагаю не вдаваться в область философии, а решить задачу:
Пусть есть строчка
111111113451111111111111111111111111111
нужно получить
111111223452222222111111111111111111111
Вот мое некрасивое решение:
--- Код: ---sub change{
my $i=1;
my %tag;
while ($_[0]=~s/(.*?)/\\x07$i/s) {
$tag{$i}=$1;
$tag{$i}=~s/1/2/g;
$i++;
}
while ($i>1) {
$i--;
$_[0]=~s/\\x07$i/$tag{$i}/g;
}
}
my $a=\'111111113451111111111111111111111111111\';
print $a."\\n";
change($a);
print $a;
--- Конец кода ---
Но я думаю, что на перле можно придумать что-нибудь покрасивее.
Или нет?
metton:
Vladn
Вот тебе решение в одну (ну ладно, в три, но их можно написать в одну ;) ) строчку ;)
--- Код: ---
my $str = "111111113451111111111111111111111111111";
$str =~ s/()(.*?)()/local($1,$2,$3);$1=~s?1?2?g; $1.$2.$3/ge;
print $str;
--- Конец кода ---
зы: 2ALL:
Только я не понял, почему при попытке регэкспить (оператором s///) непосредственно $1, $2 и $3, без их локализации, выводится ошибка: "Modification of a read-only value attempted..."
Что-то я не нашёл такого в книгах.
Vladn:
metton
Спасибо за решение, но более правильно будет записать так:
--- Код: ---my $str = "111111113451111111111111111111111111111";
$str =~ s/()(.*?)()/local($1,$2,$3);$2=~s?1?2?g; $1.$2.$3/ge;
print $str;
--- Конец кода ---
Но и этот скрипт не заработал на моем ActivePerl v5.6.1. Точнее заработал, но заработал неправильно.
А заработал у меня несколько модифицированный скрипт:
--- Код: ---my $str = "111111113451111111111111111111111111112341211";
print $str."\\n";
$str =~ s/()(.*?)()/my ($a,$b,$c)=($1,$2,$3);$b=~s?1?2?g;$a.$b.$c/ge;
print $str;
--- Конец кода ---
Но первоначально у меня стояла следующая задача: отобразить текст в как он есть. Проблема возникает тогда, когда есть символы < & и т.п. Они в браузере даже в заменяются на соответствующие символы. Казалось бы элементарное решение $str=~s/\\&/\\&/g; не помогло, т.к. оказалось, что IE & NC не заменяют последовательности &.. на символы, если эти последовательности находятся внутри комментариев (а Opera заменяет на символы везде). Например, попробуйте просмотреть в IE текст
--- Код: ---
& & <
& & <
--- Конец кода ---
Как оказалось, до сих пор встречаются умники, которые заключают JS-скрипты в комментарии (хотя, браузеры, которые не понимают JS можно найти лишь в музее), и если страницу с таким JS-скриптом обработать "казалось бы элементарным решением" и вывести в браузер, то внутри JS-скрипта будет полная ерунда. Поэтому новая задача:
необходимо обработать текст
--- Код: ---& & <
& & <
& & <
--- Конец кода ---
так, чтобы получился текст
--- Код: ---& &nbsp; &amp; &lt;
& &nbsp; &amp; &lt;
& &nbsp; &amp; &lt;
--- Конец кода ---
Мой некрасивый вариант решения:
--- Код: ---sub change{
my $i=1;
my %tag;
while ($_[0]=~s/()/\\x07$i/s) {
$tag{$i}=$1;
$i++;
}
$_[0]=~s/\\&/\\&/g;
while ($i>1) {
$i--;
$_[0]=~s/\\x07$i/$tag{$i}/g;
}
}
my $str=\'& & <
& & <
& & <\';
change($str);
print $str;
--- Конец кода ---
Может, у кого-нибудь получится красивее?
metton:
Vladn
Ну да, с лексическими переменными я тоже делал, но криво это как-то. Стрянно, почему просто $1, $2, $3 не работают в данном случае...
Vladn:
metton
Наверное, потому что они read only. Тем более, ты далее используешь =~s?1?2?g;, что приводит к перезаписи $1 $2 и $3, точнее - записи в них пустых значений.
Навигация
Перейти к полной версии