Как я могу заменить весь текст перед совпадением в замене Perl?
-
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:/;
}
Любой из левой стороны будет заменен. Если левая сторона не совпадает, ничего не будет напечатано.