-1

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

  • 前: line1 asdasdfff
  • 后: 1enil fffdsadsa

使用:

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

错误在哪里?

4

2 回答 2

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
于 2013-01-24T14:17:39.357 回答
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> );

当然,你会有记录分隔符,所以你必须考虑这些。你可以把 achomp放在外部的开头map

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

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

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

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

于 2013-01-24T13:44:35.457 回答