$all="{this, {is, some, {deeply, nested}, text}, for, you}";
while ($all=~s/{([^{}]*?)}/f($1)/seg) {}
sub f {return \{split(",",$_[0])};}
print @{$all};
Run Code Online (Sandbox Code Playgroud)
我希望$ all是一个listref,其列表包含:
{this, [reference to array], for, you}
Run Code Online (Sandbox Code Playgroud)
相反,@ {$ all}是空的.
我确信这是基本的,但我做错了什么?
注意:我有意"高举"代码在这里发布(即显示问题的最小代码).更广泛的版本是:https://github.com/barrycarter/bcapps/blob/master/playground.pl
编辑:感谢所有回答的人!笔记:
真正的f()有副作用,更新dbs等,所以我真的必须调用它.它不仅仅是将列表更改为其他内容.我不好意思没有提到这一点.
我从Mathematica导出所以"{a,b,c}"是一个列表,而不是哈希.再次,mea culpa没有提到这一点.
我知道执行此操作的"正常"方式是递归的:处理每个元素,如果元素是列表,则在列表本身上调用f().我试图"展开"递归以避免拆分嵌套的"{".如果你在里面工作,你就不必在解析时计算"{".
一个有趣的其他应用程序将是一个单行的XML解析器(差不多).
给geekosaur一个复选标记,指出哪里出错了,为什么我的方法可能是错误的.
我想我会尝试解析器方法,甚至是jrey的s/{/ [方法.
你不能$all同时成为一个迭代匹配的字符串和一个收集迭代结果的arrayref. $all将最终变成类似于字符串的东西"thisARRAY(0xdeadbeef)foryou",并将@$all其用作包符号名称,几乎肯定没有定义,因此它将自动归档为空列表.
另外,{}已经是(HASH而不是ARRAY)引用,所以你将SCALARref 返回HASHref而不是ARRAYref,正如你所期望的那样.并且{}在正则表达式中是特殊的(foo{1,3}意味着重复1到3次foo),所以你应该逃避它们.
正确的方法是收集到结果列表中,例如
my @res;
while ($all =~ /\G\{([^{}]*?)\}/sg) {
push @res, f($1);
}
Run Code Online (Sandbox Code Playgroud)
use warnings并且use strict会告诉你一些事情是错的,如果不是确切的话.使用它们.总是.
| 归档时间: |
|
| 查看次数: |
177 次 |
| 最近记录: |