Perl:反转文件中的每个单词

时间:2013-01-24 13:30:26

标签: perl reverse

我正在尝试编写一个脚本来反转每行中文件中的每个单词

  • 之前:line1 asdasdfff
  • 之后:1enil fffdsadsa

使用:

@lines = split(/\s+/, reverse($old));

错误在哪里?

2 个答案:

答案 0 :(得分:6)

您可以使用带评估的替换:

s/(\S+)/reverse $1/ge for @lines;

这将捕获所有连续的非空格,并用相反的版本替换它们。输入/输出示例:

I'm a little teapot short and stout
m'I a elttil topaet trohs dna tuots    

foobar qwerty aboo
raboof ytrewq ooba

答案 1 :(得分:3)

如果你的目标是反转每个单词到位,那么倒转整行然后拆分就是问题所在。因为反转整行会改变单词的顺序。所以你要么:

my @lines = reverse split(/\s+/, reverse($old));

或者:

my @lines = map { reverse; } split /\s+/, $old;

第一个只是简单地反转列表,第二个按顺序保留单词并反转每个单词。根据我的要求,第二个看起来更像你想要做的。将单词留在原位然后反转每个单词。 (关于map-grep链的问题是它们从右到左阅读,如果你愿意的话,继续执行任务。)


所以,你想要扭转线条。从您的预期输出(仅包含一行)中可以看出这种情况。在$old文件句柄的情况下,它不适合作为reverse的参数。您必须使用“钻石运算符”<$var>

reverse( <$old> );

将所有记录/行吸入内存并输出反转的数组。如果将其传递给split,则会出现问题。您只需要拆分数组大小的文本表示。由于数字中没有空格,因此它将包含一个包含数组大小的数组。所以你想拆分每个行......

map { [ split /\s+/ ] } reverse( <$old> );

我把它们放在一个数组中,所以你不要只是反转整个文件,每个行数组都作为一个单元保持在一起。然后你需要反转每个单词以便分开。

map { map { reverse; } split /\s+/ } reverse( <$old> );

当然,你会在那里有记录分隔符,所以你必须考虑到这些。你可以在外chomp的开头放一个map

map { chomp; map { reverse; } split /\s+/ } reverse( <$old> );

您可能希望将记录分隔符附加到每个组的末尾,因此您需要捆绑每个单词的列表:

print map { chomp; (( map { reverse; } split /\s+/ ), $\ || $/ ) } reverse( <$old> );

因此我们必须隔离map表达式,然后添加当前定义的输出记录分隔符 - 或者如果未定义,则将记录分隔符输入到每个拆分和反转行。