我有重复分隔符(逗号)的问题
字符串输入
abc : {A=[2, 2, 2], B=x, C=[1, 1, 1, 1], D=1}
Run Code Online (Sandbox Code Playgroud)
我的代码
if ($_ =~ /^(\w+)\s+:\s+\{(\S+=.*)\}/)
{
my $attr_struct = $1;
my $sub_attr_struct = $2;
$sub_attr_struct =~ s/,\s+/,/g;
my @sub_attr_struct_split = split(',',$sub_attr_struct);
foreach my $attr (@sub_attr_struct_split)
{
print "$attr_struct".".$attr\n";
}
}
Run Code Online (Sandbox Code Playgroud)
预期输出是
abc.A=2:2:2
abc.B=x
abc.C=1:1:1:1
abc.D=1
Run Code Online (Sandbox Code Playgroud)
split当逗号是要获取的字段的一部分时,很难使用逗号;分隔符模式需要一个复杂的正则表达式,这对于各种数据来说是脆弱的。\xe2\x80\xa0
相反,一种方法
\nmy ($w, $c) = /(\\w+) \\s+:\\s+ { (.+) }/x; \n\nmy @t = $c =~/ ([^=]+ = (?:\\[ [^\\]]+ \\] | \\w+) ) (?:,\\s+)? /gx; \n\ns/,\\s+/:/g for @t;\nRun Code Online (Sandbox Code Playgroud)\n在命令行程序中,用于准备测试驱动
\nperl -wE\'$_=q(abc : {A=[2, 2, 2], B=x, C=[1, 1, 1, 1], D=1}); \n say; say"-"x40;\n ($w, $c) = /(\\w+) \\s+: \\s+{ (.+) }/x; \n say $w; \n @t = $c =~/ ([^=]+ = (?:\\[ [^\\]]+ \\] | \\w+) ) (?:,\\s+)? /gx;\n s/,\\s+/:/g for @t;\n say for @t \'\nRun Code Online (Sandbox Code Playgroud)\n这可以压缩在一个正则表达式中,但我绝对同意首先将其分解的问题。
\n它打印
\nabc : {A=[2, 2, 2], B=x, C=[1, 1, 1, 1], D=1}\n----------------------------------------\nabc\nA=[2:2:2]\nB=x\nC=[1:1:1:1]\nD=1\nRun Code Online (Sandbox Code Playgroud)\n可以形成精确的所需输出:
\nmy @terms = map { "$w.$_" } @t;\nRun Code Online (Sandbox Code Playgroud)\n评论
\n首先将输入拆分为单词(之前:)和以下花句的内容。
然后在花式匹配中:所有直到=,然后=,然后[...]或者单词字符(x或1,等等)。
匹配/g对整个字符串进行全局 ( ) 运行,返回所有此类模式。但中间的内容, 是可选的 ( (?,\\s+)?),因为最后一项后面没有跟随它。
=实际数据中还能看出什么?
使用否定字符类 ( [^=]+, [^\\]]+) 提供非贪婪匹配,因为这些模式匹配序列直到该字符第一次出现。
表达式s/,\\s+/:/g for @t使用这样一个事实:在for循环中,主题变量$_在这里是迭代元素的别名;更改它会更改元素(除非它们是只读的字符串文字)。所以s///改变 的元素@t。
一般来说,这不是一个好的做法,但在这种形式中,我认为它有点像一种习语,因为它非常独特,一旦你知道它的作用,它就非常清晰和明显。如果不是,请重写得更好一些。
\n\xe2\x80\xa0例如
\nmy @t = split / (?<= \\]|=\\w) ,\\s* /x, $inside_curlies;\nRun Code Online (Sandbox Code Playgroud)\n此分割是在逗号上进行的,逗号前面是]或=\\w。它在给定的字符串上产生正确的结果,但我们不能说,=\\w+因为后视 (?<= ...)不能采用具有任意长度匹配的模式(什么\\w+)。
B=x 所以如果它可以是或 , 我们就不能像这样匹配B=x1。在较新的 Perls 中,lookbehind 适用于最多 255 个字符的可变长度匹配。所以我们可以说(?<= \\]|=\\w{1,254)),如果我们知道接下来的内容=不会更长。但这变得很尴尬。
其他数据修改很容易想象,但也不容易适应。
\n这被归为脚注,因为我认为这不是一个好的解决方案。
\n| 归档时间: |
|
| 查看次数: |
85 次 |
| 最近记录: |