【问题标题】:Can I turn a string which looks like the contents of an array into an array?我可以将看起来像数组内容的字符串转换为数组吗?
【发布时间】:2012-02-18 05:55:18
【问题描述】:

我从文本文件中读取了一个字符串,这相当于我以以下格式声明它:

$string = '["Item1_Field1","Item1_Field2","Item1_Field3"],["Item2_Field1","Item2_Field2","Item2_Field3"],["Item3_Field1","Item3_Field2","Item3_Field3"],["Item4_Field1","Item4_Field2","Item4_Field3"]';

(实际字符串包含大约 600 个项目和大约 50 个字段) 我想要做的是得到一个项目和字段的二维(嵌套)数组,这样我就可以使用类似的东西来引用它们:

print $ItemsAndFields[1][2]

这将导致(允许从零开始的数组):

Item2_Field3

在我看来,字符串的格式与您在 Perl 中声明数组的方式非常相似,所以我希望有类似于以下内容的内容允许我直接将项目分配给数组:

@ItemsAndFields = magicfunction( $string );

但我找不到任何合适的东西可以让我以这种方式使用字符串。

我能看到的唯一方法是使用 split 函数两次来创建这个数组的数组。以下内容未经测试,只是我脑海中正在进行的一项工作:

$string =~ s/\[//g;
my @items = split(/\],*/, $string);
my @ItemsAndFields = split(/\,/, $string);

我尝试查看 eval() 函数、{} 引用的使用以及搜索此站点,但很难知道我需要搜索什么。

感谢任何帮助,我是 Perl 的新手。

【问题讨论】:

    标签: arrays string perl split


    【解决方案1】:
    my $arrayRef = eval "[$string]";
    

    会给你:

    $arrayRef = [
          [
            'Item1_Field1',
            'Item1_Field2',
            'Item1_Field3'
          ],
          [
            'Item2_Field1',
            'Item2_Field2',
            'Item2_Field3'
          ],
          [
            'Item3_Field1',
            'Item3_Field2',
            'Item3_Field3'
          ],
          [
            'Item4_Field1',
            'Item4_Field2',
            'Item4_Field3'
          ]
        ];
    

    然后您可以像这样访问它:

    my $item2Field3 = $arrayRef->[1]->[2];
    

    【讨论】:

    • 为什么不 my @ItemsAndFields = eval "($string)"; 那么这正是 OP 要求的?
    【解决方案2】:

    您可以为此使用eval,但由于您的数据不需要评估,只需解析,最好使用JSON 模块之类的东西来解析它。

    use JSON 'decode_json';
    
    my $data = decode_json "[$string]";
    
    say $$_[0] for @$data;
    

    哪个打印:

    Item1_Field1 Item2_Field1 Item3_Field1 Item4_Field1

    这避免了在数据结构中评估代码的任何问题。它也应该比eval 更快。

    【讨论】:

    • 请注意eval 确实是这里的答案。此处使用 JSON 适用于嵌套数组,因为 Perl 和 JSON 具有相同的数组结构。由于散列,您通常需要eval; Perl 和 JSON 在哈希表示法上有所不同。
    • @JoelBerger => 对不起,你错了。 eval 如果有其他方法,则永远不要用于解析输入数据。如果绝对必要的话,那么Safe应该被用来尽可能的限制eval。但是处理 Perl 符号和 JSON 之间的差异可能会更好(通过在引号之间将 : 转换为 =>,或者通过找到一种方法使 JSON 在解析时使用 => 作为记录分隔符)。但由于我们不知道 OP 的数据来自哪里,因此建议 eval 既愚蠢又危险。
    • 如果数据来自不安全的来源,那么您是绝对正确的 Eric。但是 OP 有他可以看到的数据。无论如何,我把这个问题看成是,有没有办法将 Perl-ish 字符串转换为 Perl 代码。
    【解决方案3】:

    您确实在寻找eval 函数。 eval 起初难以理解的部分原因是eval 有两种不同的形式,它们非常不同。

    • eval {block}
    • eval "string"

    块形式用于捕获异常,在这里并不重要。字符串形式是真正的神奇形式。基本上它接受你的字符串并作为一个迷你 Perl 程序运行,返回最后一个评估的语句。

    因此,您的答案是:

    my @ItemsAndFields = eval "($string)";
    

    eval 的其他用途可能是

    my $name = "Joel";
    my $sub = eval 'sub { print "Hello ' . $name . '"}';
    $sub->();
    

    您可以在其中动态创建一个作为子例程引用的字符串,然后使用eval 将其激活。 (当然你可能不需要那样做动态代码生成,这只是一个例子。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      相关资源
      最近更新 更多