当我试图解析一个多行字符串(用选项卡分隔的字符串)以查找所有由制表符分隔的值时,我无意中发现了一种“奇怪”行为,在一行中使用两个拆分:
use v6.d; # 2020.01 release
my $s = "L1:C1\tL1:C2\tL1:C3\nL2:C1\tL2:C2\tL2:C3\nL3:C1\tL3:C2\tL3:C3";
say $s.split(/\n/).split(/\t/).raku;
相应的打印结果如下:
("L1:C1", "L1:C2", "L1:C3 L2:C1", "L2:C2", "L2:C3 L3:C1", "L3:C2", "L3:C3").Seq
“奇怪”行为出现在结果序列的3d和第5个成员中。似乎有一个重叠的“预期”的最后字符串的一行和第一个字符串的后续行。
我的期望是:
("L1:C1", "L1:C2", "L1:C3", "L2:C1", "L2:C2", "L2:C3", "L3:C1", "L3:C2", "L3:C3").Seq
有谁能详细解释一下这种行为的内在原因吗?
为了澄清问题,我知道正确的代码是:
$s.split(/\n/)>>.split(/\t/).flat.raku
但我的问题是“错误”代码的内部运作。Raku是怎么得到这个结果的?
发布于 2020-02-13 11:07:48
您正在拆分第一次拆分的结果,即列表;拆分方法将强制将调用的任何内容转换为字符串,然后将其拆分。列表将(通过其Str
方法)字符串化到由单个空格分隔的成员。这就是为什么一些结果字段有两个L和C对,中间有一个空格的原因。
这将得到您想要的结果:
say "L1:C1\tL1:C2\tL1:C3\nL2:C1\tL2:C2\tL2:C3\nL3:C1\tL3:C2\tL3:C3"
.split("\n")
.map( *.split( "\t" ).Slip )
因为它拆分了第一个数组的结果,然后将其转换为一个滑滑,从而使其滑入更宽的数组。
发布于 2020-02-17 14:54:03
如果希望拆分将各个部分作为一个列表,而不是列表列表,则可以使用拆分方法的变体,该变量接受要拆分的分隔符列表:
say "L1:C1,L1:C2;L1:C3\nL2:C1-L2:C2|L2:C3^L3:C1".split([",", ";", "\n", "|", "^"]).raku;
# output: ("L1:C1", "L1:C2", "L1:C3", "L2:C1-L2:C2", "L2:C3", "L3:C1").Seq
将:k
或:v
副词传递到拆分方法调用将使结果列表中的分隔符成为单独的条目;对于:k
,值将是包含匹配分隔符的分隔符列表中的索引,而:v
则将分隔符本身放在结果列表中。
https://stackoverflow.com/questions/60204278
复制相似问题