Как я могу удалить символы между < а > в Perl?
Вопрос
Мне нужно написать Perl-скрипт для чтения из файла и удаления всего, что внутри < >, даже если они находятся на разных линиях.То есть, если входные данные являются:
Hello, world. I <enjoy eating
bagels. They are quite tasty.
I prefer when I ate a bagel to
when I >ate a sandwich. <I also
like >bananas.
Я хочу, чтобы результат был:
Hello, world. I ate a sandwich. bananas.
Я знаю, как это сделать, если текст состоит из 1 строки с регулярным выражением.Но я не знаю, как это сделать с несколькими строками.В конечном счете, мне нужно иметь возможность условно удалять части шаблона, чтобы я мог генерировать параметризованные файлы для конфигурационных файлов.Я думал, что perl был бы хорошим языком, но я все еще осваиваюсь с ним.
Редактировать:Также требуется более 1 экземпляра <>
Решение
local $/;
my $text = <>;
s/<.*?>//gs;
print $text;
Другие советы
Возможно, вы захотите ознакомиться с модулем Perl Текст::Сбалансированный, часть основного дистрибутива.Я думаю, это будет вам полезно.Как правило, хочется избегать регулярных выражений для выполнения подобных действий, если текст темы, скорее всего, будет иметь внутренний набор разделителей, это может привести к очень большой путанице.
В Perl:
#! /usr/bin/perl
use strict;
my $text = <>;
$text =~ s/<[^>]*>//g;
print $text;
Регулярное выражение заменяет все , что начинается с < через первый > (включительно) и заменяет его ничем.G является глобальным (более одного раза).
Редактировать:включенные комментарии от Хайнека и хаоса
Неэффективный односторонний способ
perl -0777 -pe 's/<.*?>//gs'
то же, что и программа
local $/;
my $text = <>;
s/<.*?>//gs;
print $text;
Это зависит от того, какой большой текст вы хотите преобразовать, здесь более эффективно использовать однострочный перевод построчно
perl -pe 'if ($a) {(s/.*?>// and do {s/<.*?>//g; $a = s/<.*//s;1}) or $_=q{}} else {s/<.*?>//g; $a = s/<.*//s}'
то же, что и программа
my $a;
while (<>) {
if ($a) {
if (s/.*?>//) {
s/<.*?>//g;
$a = s/<.*//s;
}
else { $_ = q{} }
}
else {
s/<.*?>//g;
$a = s/<.*//s;
}
print;
}