Почему Perl заменяет мою строку на «1»? - PullRequest
5 голосов
/ 06 февраля 2010

У меня есть следующий код:

#$domain = domainname.co.uk
#$root = public_html
#$webpage = domainname.co.uk/foo/bar/foobar.html
my $string = ($webpage =~ s/^$domain//g);
my $linkFromRoot = $dbh->quote($root . $string);

Обычно это работает нормально, но по какой-то причине выводом является "public_html 1" вместо "public_html / foo / bar / foobar.html".

Кто-нибудь может понять почему?

Ответы [ 5 ]

11 голосов
/ 06 февраля 2010

Вы не получаете правильный ответ, потому что подстановка возвращает вам 1, то есть количество замененных элементов. См. Ответ perlfaq4 на Как подсчитать количество появлений подстроки в строке?

$domain = "domainname.co.uk";
$root = "public_html";
$webpage = "domainname.co.uk/foo/bar/foobar.html";
my $string = ($webpage =~ s/^$domain//g);
print $string."\n";

Удалите $string и просто выполните $webpage =~ s/^$domain//g;, а затем выполните объединение строк с помощью $webpage.

7 голосов
/ 06 февраля 2010

Я думаю, вы предполагаете, что круглые скобки вокруг регулярного выражения вызывают контекст списка для него. Что это не дело. Слева от оператора присваивания определяется контекст, и он скалярный. В скалярном контексте s /// возвращает количество успешных замен. Помещение круглых скобок в объявленную переменную заставляет ее делать то, что вы хотите, потому что это создает контекст списка.

Это:

my ($string) = $webpage =~ s/^$domain//;

Возвращает часть совпадений $ webpage: имя домена. Это, вероятно, не то, что вы хотите. Вы либо хотите код С.Марка:

$webpage =~ s/^$domain//;
my $linkFromRoot = $dbh->quote($root . $webpage);

Или это

my ($string) = $webpage =~ /^$domain(.+)$//;
my $linkFromRoot = $dbh->quote($root . $string);
4 голосов
/ 06 февраля 2010

Полностью не соответствует теме вашего исходного вопроса, но возможно ли, что вы на самом деле хотели:

my $webpage = URI->new("http://domainname.co.uk/foo/bar.html");
my $path = $webpage->rel("http://domainname.co.uk/");
print "public_html/$path\n";
0 голосов
/ 07 февраля 2010

Если вам не нужна другая переменная, я думаю, что приведенные выше ответы лучше, но один из моих любимых небольших приемов синтаксиса - воспользоваться тем, что присваивание является lvalue, поэтому с небольшой перестановкой скобок:

(my $string = $webpage) =~ s/^$domain//g;

Вы можете сделать копию и изменить ее в одном утверждении.

Кроме того, наряду с другими вещами, которые немного странны в этом коде, нет особого смысла в /g в паттерне, начинающемся с ^. Он не может совпадать более одного раза.

0 голосов
/ 06 февраля 2010

Как насчет

$webpage =~ s/^$domain//g;
my $linkFromRoot = $dbh->quote($root . $webpage);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...