Как заменить токен с увеличением числа в Perl? - PullRequest
3 голосов
/ 11 апреля 2009

Я хочу заменить токен в текстовом файле на номер. Токен "<count>", и я хочу, чтобы он был заменен количеством показов. Например:

This <count> is a <count> count.
The <count> count increases <count><count><count>.
<count><count><count><count><count><count>

становится:

This 1 is a 2 count.
The 3 count increases 456.
789101112

Я не совсем уверен, как это сделать, может быть, с некоторым циклом?

my $text = (the input from file, already taken care of in my script);
my $count = 1;
while( regex not found? )
{
    $text =~ s/<count>/($count);
    $count ++;
}

Ответы [ 3 ]

15 голосов
/ 11 апреля 2009
my $text = "whatever";
my $count = 1;
$text =~ s/<count>/$count++/ge;

должен сделать это за вас. / Е в конце замещения имеет все значение.

0 голосов
/ 11 апреля 2009

Вот еще один способ сделать это с помощью позиционной развертки.

Используется позиционная ссылка \ G, которая соответствует либо началу строки, либо позиции после предыдущего совпадения.

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

my $count = 1;   # start at 1; 

while ( my $line = <STDIN> ) {                            # read stdin 
    while ( $line =~ /\G.*?(<count>)/g ) {                 # scan left to right and pick out one <count> at a time.
        substr( $line, $-[1], $+[1] - $-[1], $count++ );  # replace the substring and increment
    }
    print $line;
}

Функционально он практически идентичен опубликованному решению regex-eval, просто он работает без eval. Ранее я публиковал некоторые анти-Eval страха, но это просто FUD из других менее значимых языков, не делая Eval безопасно.

Способ / e эффективно делает это:

replace_callback( \$input, $regex, sub{ 
   return $count++;
}); 

(Где заменить обратный вызов - какая-то раздутая функция, которая выполняет всю работу)

Что действительно безопасно, как яйца, просто не очевидно, что это так безопасно.

0 голосов
/ 11 апреля 2009

Вот скрипт procFile, который делает то, что вы просили:

$val = 1;                         # Initial change value.
while (<STDIN>) {                 # Process all lines.
    chomp;                        # Remove linefeed.
    $ln = $_;                     # Save it.
    $oldln = "x" . $ln;           # Force entry into loop.
    while ($oldln ne $ln) {       # Loop until no more changes.
        $oldln = $ln;             # Set lines the same.
        $ln =~ s/<count>/$val/;   # Change one occurrence if we can.
        if ($oldln ne $ln) {      # Increment count if change was made.
            $val++;
        }
    }
    print "$ln\n";                # Print changed line.
}

Вы запускаете его с cat inputFile | perl procFile и вашим примером файла:

This <count> is a <count> count.
The <count> count increases <count><count><count>.
<count><count><count><count><count><count>

генерирует:

This 1 is a 2 count.
The 3 count increases 456.
789101112
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...