Как я могу исключить часть строки, которая соответствует регулярному выражению Perl? - PullRequest
1 голос
/ 13 октября 2010

У меня есть файл с разными типами линий.Я хочу выбрать только те строки, которые имеют user-agent.Я знаю, что строка, которая имеет это что-то вроде этого.

User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; de-DE; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16

Итак, я хочу определить строку, которая начинается со строки «User-Agent», но после этого я хочу обработать остальныелинии, исключая эту строку.Мой вопрос: сохраняет ли Perl оставшуюся строку в какой-либо специальной переменной, которую я могу использовать для дальнейшей обработки?Итак, в основном я хочу сопоставить строку, которая начинается с этой строки, но после этой работы с остальной частью, исключая эту строку.

Я ищу эту строку с помощью простого регулярного выражения

/^User-Agent:/

Ответы [ 7 ]

3 голосов
/ 13 октября 2010

Решение substr :

my $start = "User-Agent: ";

if ($start eq substr $line, 0, length($start)) {
    my $remainder = substr $line, length($start);
}
3 голосов
/ 13 октября 2010

(мой $ remainder = $ str) = ~ s / ^ User-Agent: //;

3 голосов
/ 13 октября 2010
if ($line =~ /^User\-Agent\: (.*?)$/) {
    &process_string($1)
}
2 голосов
/ 14 октября 2010

Perl 5.10 имеет приятную особенность, которая позволяет вам получить простоту решений $' без проблем с производительностью.Вы используете флаг /p и переменную ${^POSTMATCH}:

 use 5.010;
 if( $string =~ m/^User-Agent:\s+/ip ) {
      my $agent = ${^POSTMATCH};
      say $agent;
      }

Хотя есть и другие приемы.Если вы не можете использовать Perl 5.010 или новее, вы используете глобальное совпадение в скалярном контексте, значение pos - это то место, где вы остановились в строке.Вы можете использовать эту позицию в substr :

 if( $string =~ m/^User-Agent:\s+/ig ) {
      my $agent = substr $string, pos( $string );
      print $agent, "\n";
      }

pos похож на @+ трюк, который Axeman показывает .Я думаю, у меня есть несколько примеров с @+ и @- в Мастеринг Perl в первой главе.

С Perl 5.14, который скоро появится, есть еще один интересный способ сделать это,Флаг /r на s/// делает неразрушающей заменой .То есть он соответствует связанной строке, но выполняет подстановку для копии и возвращает копию:

use 5.013;  # for now, but 5.014 when it's released
my $string = 'User-Agent: Firefox';
my $agent = $string =~ s/^User-Agent:\s+//r;
say $agent;

Сначала я думал, что /r глупо, но я действительно начинаю его любить.Так много всего получается с этим очень легко.Это похоже на идиому, которую M42 показывает , но это немного хитро, потому что старая идиома выполняет назначение, а затем замену, где функция /r выполняет замену, а затем назначение.Вы должны быть осторожны со своими круглыми скобками, чтобы убедиться, что происходит правильный порядок.

Обратите внимание, в этом случае, поскольку версия Perl 5.12 или более поздняя, ​​ вы автоматически получаете ограничения .

2 голосов
/ 13 октября 2010

Вы можете использовать переменную $', но не - это добавляет много накладных расходов. Вероятно, примерно так же хорошо - для тех же целей - переменная @+ или, на английском , @LAST_MATCH_END.

Итак, вы попадете туда:

use English qw<@LAST_MATCH_END>;

my $value = substr( $line, $LAST_MATCH_END[0] );
0 голосов
/ 14 октября 2010

Используйте $', чтобы получить часть строки справа от совпадения.

В других ответах о "значительном снижении производительности" много жалоб и стонов беспокоиться об этом.

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

0 голосов
/ 13 октября 2010

Вы можете использовать $' для захвата части строки после матча:

if ( $line =~ m/^User-Agent: / ) {
    warn $';
}

(Обратите внимание, что после двоеточия есть пробел.)

Но обратите вниманиес perlre :

ПРЕДУПРЕЖДЕНИЕ. Как только Perl обнаружит, что вам нужен один из $ &, $ `или $ 'в любом месте программы, он должен предоставить их для каждогообразец соответствия.Это может существенно замедлить вашу программу.Perl использует тот же механизм для получения $ 1, $ 2 и т. Д., Поэтому вы также платите цену за каждый шаблон, который содержит скобки с захватом.(Чтобы избежать этой стоимости при сохранении поведения группировки, используйте вместо этого расширенное регулярное выражение (?: ...).) Но если вы никогда не используете $ &, $ `или $ ', то шаблоны без захвата скобок не будут наказываться.Поэтому избегайте $ &, $ 'и $ `, если можете, но если вы не можете (и некоторые алгоритмы действительно ценят их), как только вы использовали их один раз, используйте их по желанию, потому что вы уже заплатилицена.По состоянию на 5.005 $ & не так дорого, как два других.

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