2014-06-16 53 views
0

我想分割这个字符串。下面的代码:分割字符串中的两个字符 - Perl

my $string = "585|487|314|1|1,651|365|302|1|1,585|487|314|1|1,651|365|302|1|1,656|432|289|1|1,136|206|327|1|1,585|487|314|1|1,651|365|302|1|1,585|487|314|1|1,651|365|302|1|1%656|432|289|1|1%136|206|327|1|1%654|404|411|1|1"; 
my @ids = split(",", $string); 

我要的是字符串中分割仅%,,有人告诉我,我可以用一个模式,这样的事情? /[^a-zA-Z0-9_]/

+8

perldoc -f split。 'split/[%,] /,..' –

+0

完美工作!谢谢! – user2524169

+0

@mpapec你为什么不发表你的评论作为答案? –

回答

3

可以使用字符类来表示一组可能匹配的单个字符。而字符类开始处的^符号会否定该类,并说“除......之外的任何匹配项”。在split的上下文中,无论哪种匹配都被视为分隔符。 '[^ a-zA-Z0-9_]可以匹配除ASCII字母'a'到'z','A'到'Z'以及数字' 0'到'9',加上下划线。在你的情况下,虽然这将正确地分割为“,”和“%”(因为它们不包含在az,AZ,0-9或_中),它也会错误地分割为“|”,以及任何其他字符不包含在您尝试的字符类中。

在你的情况下,更具体地说明要使用哪些分隔符,并且使用否定类来使用而不是;您要指定确切的分隔符而不是分隔符不能分隔的整个字符集。所以mpapec在他的评论中指出,更好的选择是[%,]

所以您的解决方案应该是这样的:

my @ids = split/[%,]/, $string; 

一旦你劈在“%”和“,”,你会带着一帮子的看起来像这样留给:585|487|314|1|1(或一些这些数字的变化)。在每种情况下,它是由'|'字符分隔的五个正整数。在我看来,你最终还是希望通过分裂'|'来打破这种情况。

您可以构建由列表列表表示的单个数据结构,其中每个顶级元素表示一个[,%]分隔字段,并且由对管道分隔字段组成的匿名数组的引用组成。下面的代码将建立一个结构:

my @ids = map { [ split /\|/, $_ ] } split /[%,]/, $string; 

时运行,你最终会像这样的东西:

@ids = ( 
    [ '585', '487', '314', '1', '1' ], 
    [ '651', '365', '302', '1', '1' ], 
    # ... 
); 

现在,一个ID中的每个字段可以进行检查和单独操作。

要了解更多关于字符类如何工作的内容,可以查看perlrequick,它对字符类有很好的介绍。有关split的更多信息,总是有perldoc -f split(如mpapec所述)。 split也在O'Reilly的书第6版Learning Perl的第9章中讨论过。

+1

令人惊讶的详细解释,+1 :) – zx81