Как я извлекаю строки между двумя разделителями строки в Perl?

Я понятия не имею, какие люди говорят о том, когда они говорят, что являются медленными, только если они брошены.

РЕДАКТИРОВАНИЕ: Если Исключения не выдаются, то это означает выполнение нового Исключения () или что-то как этот. Иначе исключение собирается заставить поток быть приостановленным, и стек, который будет обойден. Это может быть в порядке в меньших ситуациях, но в веб-сайтах интенсивного трафика, полагаясь на исключения, поскольку рабочий процесс или механизм пути выполнения, конечно, вызовут Вас проблемы производительности. Исключения, по сути, не плохи, и полезны для выражения исключительных условий

, рабочий процесс исключения в приложении.NET использует первые и вторые случайные исключения. Для всех исключений, даже если Вы ловите и обрабатываете их, все еще создается объект исключения, и платформа все еще должна обойти стек для поиска обработчика. Если Вы ловите и повторно бросаете, конечно, который собирается занять больше времени - Вы собираетесь получить исключение первого шанса, поймать его, повторно бросить его, вызывая другое исключение первого шанса, которое тогда не находит обработчик, который тогда вызывает исключение второго шанса.

Исключениями являются также объекты на "куче" - поэтому при броске тонн исключений тогда Вы вызываете и производительность и проблемы памяти.

, Кроме того, согласно моей копии "Тестирования производительности веб-приложения Microsoft.NET", записанные командой ACE:

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

Мой собственный опыт в поле показал, что сокращение исключений значительно помогло производительности. Конечно, существуют другие вещи, которые Вы принимаете во внимание, когда тестирование производительности - например, если Ваш Дисковый ввод-вывод застрелен, или Ваши запросы, находится в секунды, то это должно быть Вашим фокусом. Но нахождение и удаление исключений должны быть жизненно важной частью той стратегии.

11
задан jbatista 3 December 2010 в 17:13
поделиться

6 ответов

Вам нужен оператор триггера (более известный как оператор диапазона) ..

#!/usr/bin/env perl
use strict;
use warnings;

while (<>) {
  if (/START/../END/) {
    next if /START/ || /END/;
    print;
  }
}

Замените вызов print тем, что вы действительно хотите сделать (например, вставить строку в массив, отредактировать, отформатировать и т. д.). Я следующий - мимо строк, которые на самом деле имеют START или END , но вы можете не захотеть такого поведения. См. эту статью для обсуждения этого оператора и других полезных специальных переменных Perl.

22
ответ дан 3 December 2019 в 02:41
поделиться

Как в Perl захватить несколько строк после совпадающей?

Как это? В нем строка END - это $ ^, вы можете изменить ее на свою строку END.

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

1
ответ дан 3 December 2019 в 02:41
поделиться
while (<>) {
    chomp;      # strip record separator
    if(/END/) { $f=0;}
    if (/START/) {
        s/.*START//g;
        $f=1;
    }
    print $_ ."\n" if $f;
}

попробуйте написать код в следующий раз

1
ответ дан 3 December 2019 в 02:41
поделиться

Вы используете Vista или Windows 7? Если это так, то SetThreadLocale не работает (даже если он возвращает TRUE, вздох), и вам нужно использовать SetThreadUILanguage .

Я только что завершил приложение WTL, которое было переведено на 7 разных языков, и пользователь может переключать языки без проблем, которые вы описываете. Я использую SetThreadLocale в XP и SetThreadUILanguage в Vista / 7.

Дополнительная информация:

http://social.msdn.microsoft.com/forums/en- США / windowscompatibility / thread / d3a44b1c-900c-4c64-bdf8-fe94e46722e2 /

http: //www.curlybrace. оператор (задокументирован в perlop):

perl -ne 'print if /START/ .. /END/' file1 file2 ...

Если вам нужен текст, а не строки, вы должны использовать

perl -0777 -ne 'print "$1\n" while /START(.*?)END/gs' file1 file2 ...

. Но если вы хотите, чтобы строки от START до END были вложенными, вы столкнетесь с проблемой, описанной в вопросе в этом разделе. о сопоставлении сбалансированного текста.

Вот еще один пример использования ..:

while (<>) {
    $in_header =   1  .. /^$/;
    $in_body   = /^$/ .. eof;
# now choose between them
} continue {
    $. = 0 if eof;  # fix $.
}
5
ответ дан 3 December 2019 в 02:41
поделиться

После ответа Телемаха вещи начали выливаться наружу. Это работает как решение, которое я ищу в конце концов.

  1. Я пытаюсь извлечь строки, разделенные двумя строками (одна - со строкой, заканчивающейся на «CINFILE =»; другая, со строкой, содержащей один «#» ") отдельными строками, за исключением строк-разделителей. Это я могу сделать с помощью решения Телемаха.
  2. В первой строке есть пробел, который я хочу удалить. Я также включаю его.
  3. Я также пытаюсь извлечь каждый набор строк в отдельные файлы.

У меня это работает, хотя код можно классифицировать как уродливый; это потому, что я практически новичок в Perl. В любом случае, вот оно:

#!/usr/bin/env perl
use strict;
use warnings;

my $start='CINFILE=$';
my $stop='^#$';
my $filename;
my $output;
my $counter=1;
my $found=0;

while (<>) {
  if (/$start/../$stop/) {
    $filename=sprintf("boletim_%06d.log",$counter);
    open($output,'>>'.$filename) or die $!;
    next if /$start/ || /$stop/;
    if($found == 0) { print $output (split(/ /))[1]; }
    else { print $output $_; }
    $found=1;
  } else { if($found == 1) { close($output); $counter++; $found=0; } }
}

Надеюсь, это принесет пользу и другим. Ура.

1
ответ дан 3 December 2019 в 02:41
поделиться

Неплохо для "виртуального новичка". Одна вещь, которую вы можете сделать, - это поместить «$ found = 1» внутри блока «if ($ found == 0)», чтобы вы не выполняли это присвоение каждый раз между $ start и $ stop.

Еще одна неприятная вещь, на мой взгляд, это то, что вы открываете один и тот же обработчик файлов каждый раз, когда вводите $ start / $ stop-block.

Это показывает способ обойти это:

#!/usr/bin/perl

use strict;
use warnings;

my $start='CINFILE=$';
my $stop='^#$';
my $filename;
my $output;
my $counter=1;
my $found=0;

while (<>) {

    # Find block of lines to extract                                                           
    if( /$start/../$stop/ ) {

        # Start of block                                                                       
        if( /$start/ ) {
            $filename=sprintf("boletim_%06d.log",$counter);
            open($output,'>>'.$filename) or die $!;
        }
        # End of block                                                                         
        elsif ( /$end/ ) {
            close($output);
            $counter++;
            $found = 0;
        }
        # Middle of block                                                                      
        else{
            if($found == 0) {
                print $output (split(/ /))[1];
                $found=1;
            }
            else {
                print $output $_;
            }
        }

    }
    # Find block of lines to extract                                                           

}
1
ответ дан 3 December 2019 в 02:41
поделиться
Другие вопросы по тегам:

Похожие вопросы: