1

大二进制文件 ($data) 的摘录如下所示:

\n1ax943021C               xxx\t2447\t5
\n1ax951605B               yyy\t10400\t6
\n1ax919275  G2L           zzz\t6845\t6

前 25 个字符包含一个用空格填充的文章编号。如何将文章编号和下一列之间的所有空格转换为 \x09 ?请注意货号不同部分之间的一个或多个空格。

我尝试了一种解决方法,但是用“。{25}xxx»”覆盖了文章编号

$data =~ s/\n.{25}/\n.{25}xxx/g

有谁能帮忙吗?

非常感谢!

加里

4

4 回答 4

2

您可以unpack用于固定宽度的数据:

use strict;
use warnings;
use Data::Dumper;

$Data::Dumper::Useqq=1;
print Dumper $_ for map join("\t", unpack("A25A*")), <DATA>;

__DATA__
1ax943021C               xxx    2447    5
1ax951605B               yyy    10400   6
1ax919275  G2L           zzz    6845    6

输出:

$VAR1 = "1ax943021C\txxx\t2447\t5";
$VAR1 = "1ax951605B\tyyy\t10400\t6";
$VAR1 = "1ax919275  G2L\tzzz\t6845\t6";

请注意,Data::Dumper'Useqq选项以转义形式打印白色字符。

基本上我在这里所做的就是取出每一行,解压它,使用 2 个空格填充文本字符串(删除所有多余的空间),用制表符将这些字符串重新连接在一起并打印它们。另请注意,这会保留最后一个字符串内的空间。

于 2013-08-23T09:30:40.333 回答
1

我将这个问题解释为有一个 25 个字符宽的字段,应该去掉其尾随空格,然后在下一个字段之前用制表符分隔。否则应保留文章编号中的空格(如“1ax919275 G2L”)。

以下构造应该可以解决问题:

$data =~ s/^(.{25})/{$t=$1;$t=~s! *$!\t!;$t}/emg;

它匹配数据中每行开头的 25 个字符,然后通过去除其尾随空格并附加制表符来评估每个文章编号的表达式。

于 2013-08-23T09:38:06.453 回答
0

试一试:

$data =~ s/ +/\t/g;
于 2013-08-23T09:10:37.997 回答
0

不确定你到底是什么 - 这将匹配两列并将它们打印出来 - 带有所有原始空格。让我知道所需的输出,我会为您修复它...

#!/usr/bin/perl -w
use strict; 

my @file = ('\n1ax943021C               xxx\t2447\t5', '\n1ax951605B               yyy\t10400\t6',
'\n1ax919275  G2L           zzz\t6845\t6');

foreach (@file) {
    my ($match1, $match2) = ($_ =~ /(\\n.{25})(.*)/);
    print "$match1'[insertsomethinghere]'$match2\n";
}

输出:

\n1ax943021C               '[insertsomethinghere]'xxx\t2447\t5
\n1ax951605B               '[insertsomethinghere]'yyy\t10400\t6
\n1ax919275  G2L           '[insertsomethinghere]'zzz\t6845\t6
于 2013-08-23T09:29:21.367 回答