Я знаю, что на этом сайте много вопросов о сопоставлении многострочных регулярных выражений с perl, однако я все еще не могу понять, как сделать следующее. Поэтому любая помощь или ссылки на соответствующие вопросы будут высоко оценены.
У меня есть текстовый файл input.txt
, который структурирован с меткой поля (обозначается обратной косой чертой) и содержимым поля, например:
\x text
\y text text
text text
\z text
Содержимое поля может содержать разрывы строк, но для дальнейшей обработки мне нужно убедиться, что все содержимое поля находится на одной строке. Следующее, по-видимому, может правильно соответствовать в нескольких строках, однако оно не удаляет его, а вместо этого повторно вставляет.
#!/usr/bin/perl
$/ =undef;
{
open(my $in, "<", "input.txt") or die "impossible: $!";
open(my $out, ">", "output.txt") or die "Can't open output.txt: $!";
while (<$in>) {
s/\n([^\\])/ \1/g; # delete all line breaks unless followed by backslash and replace by a single space
print $out $_ ;
}
}
Он добавляет пробел впереди (так что я знаю, что он правильно его находит), но, тем не менее, сохраняет символ новой строки. Вывод выглядит следующим образом:
\x text
\y text text
text text
\z text
В то время как я надеялся получить это:
\x text
\y text text text text
\z text
s{\n(?!\\.)}{}g;
с соответствующим образом настроенным переводом строки, как в ответе Брайана.(?!...)
- это отрицательный просмотр вперед. Он не потребляет то, что ему соответствует, поэтому вам не нужно повторно вводить его. - person zdim   schedule 26.08.2018$/ = undef
выполняет: (1) изменяет$/
для всего блока; лучше поместить его внутрь блока и перейтиlocal $/;
(2) Поскольку$/
этоundef
, следующий<$in>
читает (глотает) весь файл; Я полагаю, что это ваше намерение. Но тогдаwhile
вводит в заблуждение; почему неmy $text = <$in>
? // Своего рода идиома:my $text = do { local $/; open ... ; <$fh> };
, а затем процесс$text
. Есть также модули, которые делают это в одну строку, напримерPath::Tiny
. - person zdim   schedule 27.08.2018