我正在尝试编写一个脚本来反转每行中文件中的每个单词
line1 asdasdfff
1enil fffdsadsa
使用:
@lines = split(/\s+/, reverse($old));
错误在哪里?
答案 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
表达式,然后添加当前定义的输出记录分隔符 - 或者如果未定义,则将记录分隔符输入到每个拆分和反转行。