.3 .3.1 .3.1.1 .2 .2.1 .2.1.1 .2.1.1.1 .1
Найти максимальное число с максимальным вложением единичек. Решение, если убрать точки, будет максимальным числом. Его и надо выделить:
#!/usr/bin/perl -w $_=qq~.3 .3.1 .3.1.1 .2 .2.1 .2.1.1 .2.1.1.1 .1 ~; print ".", join "." => split m!! => @{[reverse sort {$a <=> $b} grep{s!\.!!g} split m%\n%]}[0]; print "\n";
Как это работает: конструкця @{[ тут действия со списками ]} возвращает массив элементов, из которого можно выделить нужный по номеру элемента массива @{[blah-blah]}[0]. В переменной $_ содержится искомая "строка" из цифр, поэтому её можно разбивать по переводу каретки: split m%\n%. После split m%\n% для grep{s!\.!!g} возвращается список, который из каждого элемента списка вырезает символ точки(экранированный символ, т.к. символ точки в regex означает любой символ). Дальше возвращается список чисел без точки, которые сортируются при помощи sort {$a <=> $b}. Скобки {$a <=> $b} нужны для того, чтобы была произведена числовая, а не символьная сортировка. Т.е. в случае print join "\n" => sort {$a <=> $b} grep{s!\.!!g} @blah-blah функция sort вернет такой список, где максимальным будет число, содержащее в начале себя тройку как максимальное число, т.е. критическим будет "старший бит":
1 2 21 211 2111 3 31 311
далее при помощи reverse оборачивается возвращаемый sort список и берется нулевой элемент массива, состоящий из числа(в данном случае) 2111(что как число 2111 в целом больше, чем 311). Этот нулевой элемент затем режется по символу ноль(или по пустому символу, ведь между цифрой 2 и 1 не стоит ничего, вот по этому то ничего и режется): split m!! => @{[blah-blah]}[0]. Обычно в конструкции split ставятся два косых слеша split //, $string; эти два косых слеша есть не что иное как поиск по подстановке m//. А при указании буквы m в регулярном выражении слеши можно заменять любыми символами, например split mЫЫ. Далее при обычном синтаксисе ставится запятая, эту запятую можно заменить на стрелочку => без потери функциональности. Итого имеем split m!! => @{[blah-blah]}[0], т.е. массив, который нужно вывести в прежнем виде, т.е. .2.1.1.1, чего и делаем: print ".", join "." => split m!! => @{[blah-blah]}[0]
Другое более короткое решение той-же задачи от Artem Chuprina(from fido7.ru.perl):
perl -lne 'if (/(\d+)/ && ($1 > $num || ($1 == $num && length($_) > length($res)))) { $num = $1; $res = $_ }; END { print $res }' test.dat