Сопоставление с образцом Perl - PullRequest
1 голос
/ 24 августа 2010

У меня есть такой текстовый файл это мусорная линия это мусорная строка2 это мусорная строка3 message1 это первая строка текста это вторая строка текста это третья строка текста это четвертая строка текста это пятая строка текста message1_end следующая строка

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

Как это сделать в Perl ??

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

Senthil.

Ответы [ 5 ]

3 голосов
/ 24 августа 2010
use strict;
use warnings;

open my $fh, '<', 'filename' or die "can't open 'filename' for reading : $!"
while(<$fh>) {
    chomp;
    if(/^message1$/ .. /^message1_end$/) {
        print $_,"\n" unless($_ eq 'message1' or $_ eq 'message1_end');
    }
}
close $fh;
3 голосов
/ 24 августа 2010

Может быть, это работает для вас.

open(YOURFILE,"./input.txt");
while (<YOURFILE>) {
        if (/message1/ .. /message1_end/) {
                printf "%s",$_;
        }
}
close(YOURFILE);
1 голос
/ 24 августа 2010

Я не думаю, что мы получим идеальный ответ на этот вопрос, потому что он такой расплывчатый, но здесь идет.буферы для упрощения вашей работы.Короче говоря, вы можете ссылаться на текстовые группы (блоки внутри ()) внутри регулярного выражения таким же образом, как вы делаете после инициализации.Вы просто ссылаетесь на них обратной косой чертой (\) вместо знака доллара ($).

Этот код предполагает, что у вас есть весь доступный для поиска буфер.Если вы хотите сделать это построчно, вам понадобится счетчик тегов (или другой подобный механизм), чтобы убедиться, что вы можете обрабатывать рекурсивные строки (если ваш блок сообщений сам по себе может содержать блоки сообщений)

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

my $buf = 'this is a junk line
this is a junk line2
this is a junk line3
message1
this is first line of text
this is second line of text
this is third line of text
this is fourth line of text
this is fifth line of text
message1_end
the next line';

if($buf =~m/(message\d)(.*?)(\1_end)/sg) {
    my $message = $2;
    # ...
}

Здесь \d соответствует одной цифре (см. Ссылку perldoc), а \1 соответствует тому же значению, что и $1 ("message1").Поскольку маркер начала отличается от маркера конца только на «_end», мы используем маркер начала, чтобы создать искомый маркер конца.Благодаря этому код будет отлично работать для нескольких сообщений («message1», «message2», ..).

0 голосов
/ 24 августа 2010

Другой подход, если входной файл помещается в память:

#!/usr/bin/perl

local $/=undef;
open FILE, "input.txt" or die "Couldn't open file: $!";
$string = <FILE>;
close FILE;

print $1 if ($string =~ /message1(.*)message1_end/sm);
0 голосов
/ 24 августа 2010

Вы можете сделать:

open F,"<","input.txt" or die; # try to open the file.
while(<F>) { # loop through each line of the file.
        last if(/^message1_end\n$/); # break if message end is found.
        $messsage.=$_ if($start); # append to message
        $start = 1 if(/^message1\n$/); # set start to 1 to start appending.
}

print $messsage;
...