Вы делаете это в цикле :
next if ($line =~ /ABC/);
Итак, вы читаете файл, если строка содержит ABC
где-нибудь в этой строке, вы пропустите линию. Однако для каждой другой линии вы выполняете замену. В конце концов, вы заменяете строку на всех других строках и печатаете ее, а также не распечатываете свои ярлыки.
Вот что вы сказали:
- Я долженчитать файл, пока яне найтилинии сэтикеткой:
- После того, как метка найдена
- У меня естьчитайте следующую строку изамените слово в строке, следующей за меткой.
Итак:
- Вы хотите прочитать файл строку за строкой.
- Если линия совпадает с маркировкой
- прочитать следующую строку
- заменить текст на линии
- Распечатайте линию
По этим направлениям:
use strict;
use warnings; # Hope you're using strict and warnings
use autodie; # Program automatically dies on failed opens. No need to check
use feature qw(say); # Allows you to use say instead of print
open my $fh, "<", "file1.txt"; # Removed parentheses. It's the latest style
while (my $line = <$fh>) {
chomp $line; # Always do a chomp after a read.
if ($line eq "ABC:") { # Use 'eq' to ensure an exact match for your label
say "$line"; # Print out the current line
$line = <$fh> # Read the next line
$line =~ s/old/new/; # Replace that word
}
say "$line"; # Print the line
}
close $fh; # Might as well do it right
Обратите внимание, что когда я использую say
, мне не нужно ставить \n
в конце строки. Кроме того, выполнив мой chomp
после моего чтения, я легко смогу сопоставить ярлык, не беспокоясь о \n
на конце.
Это делается именно так, как вы сказали, это должно быть сделано, но есть пара вопросов. Во-первых, когда мы делаем $line = <$fh>
, нет никакой гарантии, что мы действительно читаем строку. Что делать, если файл заканчивается прямо там?
Кроме того, это плохая практика для чтения файла в нескольких местах. Это затрудняет сохранение программы. Чтобы обойти эту проблему, мы будем использовать переменную . Это позволяет нам знать, если линия, прежде чем был ярлыком или нет:
use strict;
use warnings; # Hope you're using strict and warnings
use autodie; # Program automatically dies on failed opens. No need to check
use feature qw(say); # Allows you to use say instead of print
open my $fh, "<", "file1.txt"; # Removed parentheses. It's the latest style
my $tag_found = 0; # Flag isn't set
while (my $line = <$fh>) {
chomp $line; # Always do a chomp after a read.
if ($line eq "ABC:") { # Use 'eq' to ensure an exact match for your label
$tag_found = 1 # We found the tag!
}
if ($tag_found) {
$line =~ s/old/new/; # Replace that word
$tag_found = 0; # Reset our flag variable
}
say "$line"; # Print the line
}
close $fh; # Might as well do it right
Конечно, я бы предпочел, чтобы устранить загадочные значения. Например, тег должен быть переменной или константой. То же самое со строкой, которую вы ищете, и с строкой, которую вы заменяете.
Вы упомянули это слово, так что ваша регулярная замена выражения следует, вероятно, выглядеть следующим образом:
$line =~ s/\b$old_word\b/$new_word/;
The \b
знак границы слова. Таким образом, если вы предположите, заменить слово кот с собакой, вы не получите споткнулись на линии, которая говорит:
The Jeopardy category is "Say what".
Вы не хочешь, чтобы изменить category
к dogegory
,
Сообщите нам, что вы ожидали и что видели. – gravitas
Это домашнее задание? Если да, вернитесь назад и снова прочитайте свои заметки. – alexmac
После того, как матч найден, он не может перейти к следующей строке. Похоже, что мое следующее утверждение неверно. Любые идеи, как включить это ...? – user3271367