2012-03-05 98 views
0

我有以下语法的输入文件:perl的分割功能的使用

00000 INFO [IVS ] reset receiver 
00000 INFO [IVS ] reset transmitter 
00331 INFO [IVS ] sync detected  

所需数据的形式

frame=0000 
info=INFO 
TYPE=[IVS ] 
message=reset receiver 

($frame,$info,$type,$message)=split(what would be the argument?); 

注:括号前IVS后的空间,所以不能使用空间作为分隔器。

+0

是您的输入固定的宽度,选项卡/空格分隔,或其他什么东西?为了正确分割数据,您需要知道数据是如何生成的。所以:找出答案。 – TLP 2012-03-05 22:41:25

回答

2

我同意@hobbs,但你应该使用扩展格式复杂的正则表达式:

while(my $line = <DATA>){ 
    chomp $line; 

    my ($frame, $info, $type, $message) = 
    $line =~ m{ 
     \A  # start at the beginning of the string 
     (\d+)  # capture a string of digits  --> $frame 
     \s+  # skip the white space 
     (\S+)  # capture a string of non-spaces --> $info 
     \s+  # skip the white space 
     (  # start a capture     --> $type 
     \[  # capture an opening bracket 
     [^\]]* # capture everything that's not a closing bracket 
     \]  # capture the closing bracket 
    )   # end the capture 
     \s+  # skip the white space 
     (.*)  # capture the remainder of the line --> $message 
    }msx; 

    print "\$frame = $frame\n"; 
    print "\$info = $info\n"; 
    print "\$type = $type\n"; 
    print "\$message = $message\n"; 
    print "\n"; 
} 

__DATA__ 
00000 INFO [IVS ] reset receiver 
00000 INFO [IVS ] reset transmitter 
00331 INFO [IVS ] sync detected 
7

错误的问题。你不想使用拆分。经验法则是:当你知道你的数据是什么样的时候使用正则表达式匹配;当你知道你的分隔符是什么样的时候使用分割。

my ($frame, $info, $type, $message) = 
    $data =~ /(\d+) (\S+)\s+\[(\S+)\s*\] (.*)/; 

将是一个不错的开始。

+0

感谢,同时也你能指出我的一些网站有一个良好的开端学习Perl的? – fammi 2012-03-05 21:35:19

2

要分割的空间,只要空间后面没有]。这意味着您想要在正则表达式中使用负向预测。不要忘记,split()可以将正则表达式作为其第一个参数。它也可以采取它返回的字段的数量,所以如果你这样做:

my ($frame, $info, $type, $message) = split(/\s+(?!])/, $line, 4); 

...然后你会得到你想要的。

split()分割为一个或多个空格字符,后面跟着]。它还返回四个字段,这样你就不会分手了你的$message场(一切之后第三裂只会在$message结束)。

+0

感谢,乐于助人,我是新来的Perl中,在哪里学网页上的任何建议? – fammi 2012-03-05 21:39:35

+0

有关正则表达式的官方文档主要在[perlretut](http://p3rl.org/retut)和[perlre](http://p3rl.org/perlre)中。 - 要一般学习Perl,请相信http://learn.perl.org和http://perl-tutorial.org上提供的资源。你可以通过搜索堆栈溢出来找到这些信息,这绝不是一个难得的问题。 – daxim 2012-03-05 22:37:59

+0

@fammi:另请参见[Modern Perl](http://www.onyxneon.com/books/modern_perl/index.html)。它可以免费以各种格式下载。 – 2012-03-05 22:48:43

3

我爱正则表达式,但... TIMTOWTDI为好。 )

while (<DATA>) { 
    printf "frame=%s\ninfo=%s\nTYPE=%s\nmessage=%s\n", 
    unpack("A6 A6 A7 A*", $_); 
} 

__DATA__ 
00000 INFO [IVS ] reset receiver 
00000 INFO [IVS ] reset transmitter 
00331 INFO [IVS ] sync detected 

严重,不过,问题是,它可能会更好您的数据字符串分割一个简单的unpack是的,解包很简单,它只是需要一点练习的...))比一些扭曲的正则表达式 - 当然,如果所有数据列都有固定的宽度。但有时候就是这样。 )