5

我需要编写一个 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 个以上的 <> 实例

4

4 回答 4

6

您可能想查看一个 Perl 模块Text::Balanced,它是核心发行版的一部分。我想它会对你有所帮助。通常,如果主题文本可能具有一组内部分隔符,则希望避免使用正则表达式来执行此类操作,它会变得非常混乱。

于 2009-04-10T14:24:24.827 回答
6

在 Perl 中:

#! /usr/bin/perl   
use strict;

my $text = <>;
$text =~ s/<[^>]*>//g;
print $text;

正则表达式替换以 < 到第一个 > (包括)开头的任何内容,并将其替换为任何内容。g 是全局的(不止一次)。

编辑:纳入 Hynek 和混乱的评论

于 2009-04-10T14:28:46.410 回答
4
local $/;
my $text = <>;
s/<.*?>//gs;
print $text;
于 2009-04-10T14:51:00.723 回答
1

无效的单线方式

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;
}
于 2009-04-10T14:40:56.630 回答