Perl String форматирование - PullRequest
0 голосов
/ 07 марта 2011

Вот строка

[Move] [Source] [Destination]

Теперь я хочу переместить «move», «source», «destination»в переменные.

Это мой код

  #Try grab the "move" part.
  $data = "[ Move ] [ Source ] [ Destination ]"
  $start = index($data, '[') + 2;
  $end   = index($data, ']') - 2; #The +- 2 is to get rid of the spaces
  $cmd = substr $data, $start, $end; #This does not work. No idea why.
  $data = substr $data,  $end;
  $start = index($data, '[') + 2;
  $end   = index($data, ']') - 2;
  $source = substr $data, $start, $end;
  $data = substr $data,  $end;
  $start = index($data, '[') + 2;
  $end   = index($data, ']') - 2;
  $destination = substr $data, $start, $end;

Заранее спасибо.

Ответы [ 4 ]

4 голосов
/ 07 марта 2011

Может быть, что-то вроде этого:

my $input = '[ Move ] [ Source ] [ Destination ]';
my ($mov, $src, $dst) = $input =~ /\[ \s* (.*?) \s* \]/gx;
print "$mov $src $dst\n";
1 голос
/ 07 марта 2011

Много способов сделать это в Perl.Одним из них является использование регулярных выражений:

if ($data =~ /^\[([^\]]+)\]\s*\[([^\]]+)\]\s*\[([^\]]+)\]/) {
    my $command = $1;
    my $source = $2;
    my $destination = $3;
}
else {
    die "Didn't match\n";
}

Это немного уродливо.В основном \[ и \] соответствуют вашим квадратным скобкам.Вы должны поставить перед ними обратную косую черту, потому что скобки магические в регулярных выражениях.[^\]] соответствует незамкнутым скобкам.[^x] означает что угодно, кроме x.Знак плюс на конце означает, по крайней мере, один.Таким образом, [^\]]+ соответствует как можно большему числу символов, пока не дойдет до другой закрывающей скобки.Изогнутые скобки вокруг выражения сохраняют его в переменных $1, $2 и $3.Я повторяю это для каждого элемента, с которым я сопоставляюсь.

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

Другой способ - использовать команду split:

$data =~ s/^\[(.*)\]$/$1/;
my ($move, $source, $destination) = split (/\]\s*\[/, $data);

В первой строке удаляются префиксные и добавляющие скобки, а затем я разделяю скобки "] [".Опять же, я использую регулярные выражения.

Регулярные выражения - это кровь Perl, и вы должны узнать о них как можно больше.Perl берет стандартные регулярные выражения Unix и расширяет их немного.Вы можете ввести perldoc perlre , чтобы найти документацию о регулярных выражениях и о том, как они используются, но это скорее справочное руководство, а не учебник.Вы также можете попробовать perldoc perlrequick , который является больше учебником.

0 голосов
/ 07 марта 2011

Прежде всего, есть ли причина, по которой вы делаете это таким образом, вместо того, чтобы использовать регулярные выражения для сбора интересных данных?

my ($cmd, $source, $destination) = $data =~ /^\[ ([^]]*) \]\[ ([^]]*) \]\[ ([^]]*) \]$/`

Что касается того, почему опубликованный вами код не работает,строка, которую вы говорите, не работает, на самом деле работает просто отлично - $cmd получает текст «Move» так, как должен.Но после того, как вы удалите «Move» из $data, посмотрите на то, что у вас осталось: «e] [Source] [Destination]» В следующий раз, когда вы установите $start, это работает нормально, но установка $end находит first ] в строке, поэтому $source возвращает substr из позиции 6 в позицию 0;поскольку диапазон заканчивается до его начала, это пустая строка.Настройка $destination имеет ту же проблему, поэтому она также пуста.

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

0 голосов
/ 07 марта 2011

Есть несколько способов сделать это.

  1. Разделить строку на ] [ и убрать лишние скобки из полей, например.

    my @strings = 
        map { s/^[|]$//; $_ } 
        split '] [', $input;
    
  2. Или используйте регулярное выражение для извлечения каждого бита строки, заключенного в квадратные скобки.

    my @strings = ( $input =~ m{\[\s*(.*?)\s*\]}g );
    

Однако, эти подходы могут упасть, если выимеют вложенные квадратные скобки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...