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


Автор: DiverD 20.9.2006, 11:05
Есть массив с урлами вида: 

@old_array
Код

http://forum.vingrad.ru/index.php?act=Mail&CODE=00&MID=26457
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454
http://forum.vingrad.ru/index.php?act=Main&LOL=00&MID=21434
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=22345
http://forum.vingrad.ru/index.php?act=SC&c=1
http://forum.vingrad.ru/index.php?act=SC&c=2
http://forum.vingrad.ru/index.php?act=НН&c=3

...
...
Как сдесь видно они почти одинаковы за исключением того что в их переменных разные значения.
мне нужна добавлять из етога массив в другой скажем в цикле foreach те элементы которые неодинаковы именами переменных а не их значений.
Из приведенного примера результат должен быть таким:

@new_array
Код

http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454
http://forum.vingrad.ru/index.php?act=SC&c=2
http://forum.vingrad.ru/index.php?act=НН&c=3
http://forum.vingrad.ru/index.php?act=Main&LOL=00&MID=21434


Помогите пожалуйсто.

Автор: nitr 20.9.2006, 11:55
лучше уточнить...
почему к примеру выбираем второй из двух
Код

http://forum.vingrad.ru/index.php?act=Mail&CODE=00&MID=26457
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454

Автор: nitr 20.9.2006, 13:46
вот попробуй переделать... или объясни понятней что хочешь smile
Код

#!perl -w
############
#
# уникальные по именам параметров, и попадают значения последних урл
#
#############
use strict;

my @urls = qw(
http://forum.vingrad.ru/index.php?act=Main&CODE=00&MID=26457
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454
http://forum.vingrad.ru/index.php?act=Main&LOL=00&MID=21434
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=22345
http://forum.vingrad.ru/index.php?act=SC&c=1
http://forum.vingrad.ru/index.php?act=SC&c=2
http://forum.vingrad.ru/index.php?act=HH&c=3);

my $hash;
foreach (@urls) {
    my $str = $_;
    1 while $str =~ s/(\?|\&)(\S+?\=)([^\b&]+)/$1$2/g;    
    $hash->{$str} = $_;
}
foreach (sort keys %$hash) {
    print $hash->{$_}."\n";
}

Автор: DiverD 20.9.2006, 13:57
Щас на работе перла пока нету не могу проверить твой код.
Мы 2й из 2х не выбираем, щас поясню с начала:

Вот список урлов представим что они в массиве:
http://forum.vingrad.ru/index.php?act=Main&CODE=00&MID=26457 # 1й урл будет уникален
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454 # будет уникален
http://forum.vingrad.ru/index.php?act=Main&LOL=00&MID=21434 # будет уникален
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=22345 # такой уже есть - это 2й урл
http://forum.vingrad.ru/index.php?act=SC&c=1 # уникален
http://forum.vingrad.ru/index.php?act=SC&c=2 # уже есть - это придыдущий
http://forum.vingrad.ru/index.php?act=HH&c=3 # уже есть - см выше

Из етога массива дожны быть выбраны те урлы которые уникальны по своим именнам переменных:
http://site.com/index.php?[parm_name]={value}&[new_parm_name]={values}
                                          ^^^^^^^^                  ^^^^^^^^^^^^

Автор: nitr 20.9.2006, 14:22
так и работает мой код ;)
только измени чтоб не

Цитата(nitr @  20.9.2006,  13:46 Найти цитируемый пост)
############## уникальные по именам параметров, и попадают значения последних урл##############


только вот всё же ты несовсем пояснил... код можно доработать ско-ка угодно раз ;)


Код

http://forum.vingrad.ru/index.php?act=Main&CODE=00&MID=26457 # 1й урл будет уникален
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454 # будет уникален

они не уникальны smile между собой !!!!! (по параметрам ;) )
смотри убираем нафиг значения параметров ;) и получаем
Код

http://forum.vingrad.ru/index.php?act=...&CODE=...&MID=...
http://forum.vingrad.ru/index.php?act=...&CODE=...&MID=...

так что мой код работает, но если тебе результат всё же другой, то сам перефразируй и ОБДУМАЙ что ты хошь ;)

Автор: DiverD 20.9.2006, 16:30
Большое спасибо нитр все клэба.

Автор: amg 21.9.2006, 05:35
Здесь уже стало традицией (почти) любое решение сводить к однострочнику. smile  Вот:
Код

@urls = qw(
http://forum.vingrad.ru/index.php?act=Main&CODE=00&MID=26457
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=23454
http://forum.vingrad.ru/index.php?act=Main&LOL=00&MID=21434
http://forum.vingrad.ru/index.php?act=File&CODE=00&MID=22345
http://forum.vingrad.ru/index.php?act=SC&c=1
http://forum.vingrad.ru/index.php?act=SC&c=2
http://forum.vingrad.ru/index.php?act=HH&c=3);

@new_array = grep {! $hash{"@{[/(&|^)(.*?)=/g]}"}++} @urls;

print "$_\n" foreach (@new_array);

Автор: nitr 21.9.2006, 09:18
amg, эту традицию надо во что-то записать... как поговорил со знающими людьми это называется ТимТоуди или по-простому перлгольф... имхо надо сделать для этого что-то ;)

Автор: amg 21.9.2006, 10:28
ТимТоуди - это от "There Is More Than One Way To Do It (TIMTOWDI)", кажется, не переврал - имеется много больше одного способов сделать что-нибудь. А еще в Perl'е есть целая субкультура - one-liners - однострочники, когда достаточно нетривиальную программу запихивают в одну небольшую строку. И то, и другое лично мне очень нравится, хотя хорошо ли это на самом деле - вопрос сугубо философский.

Кстати, у меня собрана довольно полная коллекция Perl one-liners (несортированная, правда). Например:
Код

# Удаление повторяющихся строк из файла
perl -i -ne '$s{$_}++ || print' file

Такие однострочники весьма помогают мне в Windows, благодаря им Perl заменяет многие из юниксовых core utils. С удовольствием поделюсь, если кому интересно. Эту коллекцию еще бы до ума довести...

Автор: nitr 21.9.2006, 10:46
модера попроси отдельный подраздел сделать smile 
закрытый наверное... лучше...
и туда кинь свою коллекцию... будем добавлять или обновлять как-нить.. тож продумать надо, чтобы не засорять... 

Автор: amg 21.9.2006, 11:02
Тогда для начала я просто ссылку дам: http://limor1.nioch.nsc.ru/one-liners. А там видно будет.

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