perl的分割功能的使用
我有以下语法的输入文件: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后的空间,所以不能使用空间作为分隔器。
我同意@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
错误的问题。你不想使用拆分。经验法则是:当你知道你的数据是什么样的时候使用正则表达式匹配;当你知道你的分隔符是什么样的时候使用分割。
my ($frame, $info, $type, $message) =
$data =~ /(\d+) (\S+)\s+\[(\S+)\s*\] (.*)/;
将是一个不错的开始。
感谢,同时也你能指出我的一些网站有一个良好的开端学习Perl的? – fammi 2012-03-05 21:35:19
要分割的空间,只要空间后面没有]
。这意味着您想要在正则表达式中使用负向预测。不要忘记,split()
可以将正则表达式作为其第一个参数。它也可以采取它返回的字段的数量,所以如果你这样做:
my ($frame, $info, $type, $message) = split(/\s+(?!])/, $line, 4);
...然后你会得到你想要的。
此split()
分割为一个或多个空格字符,后面跟着]
。它还返回四个字段,这样你就不会分手了你的$message
场(一切之后第三裂只会在$message
结束)。
感谢,乐于助人,我是新来的Perl中,在哪里学网页上的任何建议? – fammi 2012-03-05 21:39:35
有关正则表达式的官方文档主要在[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
@fammi:另请参见[Modern Perl](http://www.onyxneon.com/books/modern_perl/index.html)。它可以免费以各种格式下载。 – 2012-03-05 22:48:43
我爱正则表达式,但... 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
(是的,解包很简单,它只是需要一点练习的...))比一些扭曲的正则表达式 - 当然,如果所有数据列都有固定的宽度。但有时候就是这样。 )
是您的输入固定的宽度,选项卡/空格分隔,或其他什么东西?为了正确分割数据,您需要知道数据是如何生成的。所以:找出答案。 – TLP 2012-03-05 22:41:25