Программирование > Регулярные выражения

Все, кроме выражения

<< < (2/3) > >>

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;
--- Конец кода ---


Но первоначально у меня стояла следующая задача: отобразить текст в как он есть. Проблема возникает тогда, когда есть символы &nbsp; < &amp; и т.п. Они в браузере даже в заменяются на соответствующие символы. Казалось бы элементарное решение $str=~s/\\&/\\&amp;/g; не помогло, т.к. оказалось, что IE & NC не заменяют последовательности &.. на символы, если эти последовательности находятся внутри комментариев (а Opera заменяет на символы везде). Например, попробуйте просмотреть в IE текст
--- Код: ---

& &nbsp; &amp; &lt;

& &nbsp; &amp; &lt;


--- Конец кода ---

Как оказалось, до сих пор встречаются умники, которые заключают JS-скрипты в комментарии (хотя, браузеры, которые не понимают JS можно найти лишь в музее), и если страницу с таким JS-скриптом обработать "казалось бы элементарным решением" и вывести в браузер, то внутри JS-скрипта будет полная ерунда. Поэтому новая задача:

необходимо обработать текст
--- Код: ---& &nbsp; &amp; &lt;

& &nbsp; &amp; &lt;

& &nbsp; &amp; &lt;

--- Конец кода ---
так, чтобы получился текст
--- Код: ---&amp; &amp;nbsp; &amp;amp; &amp;lt;

&amp; &amp;nbsp; &amp;amp; &amp;lt;

&amp; &amp;nbsp; &amp;amp; &amp;lt;
--- Конец кода ---


Мой некрасивый вариант решения:
--- Код: ---sub change{
 my $i=1;
 my %tag;
 while ($_[0]=~s/()/\\x07$i/s) {
  $tag{$i}=$1;
  $i++;
  }
 $_[0]=~s/\\&/\\&amp/g;
 while ($i>1) {
  $i--;
  $_[0]=~s/\\x07$i/$tag{$i}/g;
  }
 }

my $str=\'& &nbsp; &amp; &lt;

& &nbsp; &amp; &lt;

& &nbsp; &amp; &lt;\';
change($str);
print $str;
--- Конец кода ---


Может, у кого-нибудь получится красивее?

metton:
Vladn
Ну да, с лексическими переменными я тоже делал, но криво это как-то. Стрянно, почему просто $1, $2, $3  не работают в данном случае...

Vladn:
metton
Наверное, потому что они read only. Тем более, ты далее используешь =~s?1?2?g;, что приводит к перезаписи $1 $2 и $3, точнее - записи в них пустых значений.

Навигация

[0] Главная страница сообщений

[#] Следующая страница

[*] Предыдущая страница

Sitemap 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 
Перейти к полной версии