Как я могу заменить весь текст перед совпадением в замене Perl?

StackOverflow https://stackoverflow.com/questions/998193

  •  14-09-2019
  •  | 
  •  

Вопрос

Я читаю каждую строку входного файла (в) и печатаю строку, чтение в выходной файл (OUT) Если строка начинается с одного из шаблонов, скажем, «AB», «CD», «EF», «GH» , «IJ» и т. д. Мне нужно заменить «шаблон» на «mypattern», т.е. печатать текущую строку на файл, но заменить весь текст перед первым событием «:» с «mypattern». Как лучше всего это сделать?

В настоящее время у меня есть:

while ( <IN> )
{ 
    print FILE if /^ab:|^bc:|^ef:|^gh:/;
}

Я не уверен, поможет ли замена подстрасти, поскольку «шаблон» может быть «AB» или «CD» или «EF» или «GH» и т. Д. и т. Д. и т. Д.

Спасибо! Биографический

Это было полезно?

Решение

sub replacer {

    $line = shift;
    $find = shift;
    $replace = shift;

    $line =~ /([^:]+):/
    if ($1 =~ /$find/) { 
         $line =~ s/([^:]+):/$replace/ ;
         return $line;      
    }
    return ;

}

while (<IN>)
{
    print OUT replacer ($_,"mean","variance");
    print OUT replacer ($_,"pattern","newPattern");
}

Мой Perl немного ржавый, поэтому синтаксис может быть не точным.

редактировать: Поместите это в функцию для вас.

Другие советы

В целом делайте это как:

my %subst = ( 'ab' => 'newab', 'bc' => 'newbc', 'xy' => 'newxy' );
my $regex = join( '|', map quotemeta, sort { length($b) <=> length($a) } keys %subst );
$regex = qr/^($regex):/;

while ( <IN> ) {
    print FILE if s/$regex/$subst{$1}:/;
}

Сорт ставит самые длинные сначала, так что если данные имеют AB :: и AB и AB: заменяются, AB: используется вместо AB.

Оператор замены Perl по умолчанию (A) использует первый матч, (b) заменяет только одно совпадение и (c) возвращает True, если была сделана замена, и ложь, если это не так.

Так:

while ( <IN> )
{ 
    if (s/<pattern1>:/<replace1>/ ||
        s/<pattern2>:/<replace2>/) {
       print FILE;
    }
}

Должен работать на вас. Обратите внимание, что из-за короткого замыкания будет сделано только одна замена.

while ( <IN> )
{ 
  s/^pattern:/myPattern:/;
  print OUT
}

Это может быть то, что вы хотите:

$expr = "^(ab)|(cd)|(ef)|(gh)|(ij)";
while (<IN>)
{
    if (/$expr:/)
    {
        s/$expr/$myPattern/;
        print FILE;
    }
}

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

while ( <IN> )
{ 
    print FILE if s/^(ab|bc|ef|gh):/MyPattern:/;
}

Любой из левой стороны будет заменен. Если левая сторона не совпадает, ничего не будет напечатано.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top