分裂字符串中的两个字符 - Perl

时间:2014-06-16 14:24:43

标签: regex string perl split

我正在尝试拆分此字符串。这是代码:

 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_]/

1 个答案:

答案 0 :(得分: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(或者这些数字的某些变体)。在每种情况下,它是由' |'分隔的五个正整数。字符。我觉得你最终还是希望通过拆分&{39} |来解决这些问题。

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

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

当它运行时,你最终会得到这样的结果:

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

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

要了解有关字符类如何工作的更多信息,可以查看perlrequick,它对字符类有很好的介绍。有关split的更多信息,请始终perldoc -f split(如 mpapec 所述)。 O {Reilly的书,学习Perl,第6版的第9章也讨论了split