PHP:将字符串转换为嵌套数组

Posted

技术标签:

【中文标题】PHP:将字符串转换为嵌套数组【英文标题】:PHP: Converting a String into a Nested Array 【发布时间】:2014-03-16 04:15:12 【问题描述】:

我正在使用Laravel 并尝试编写一个工匠命令,该命令接受一个参数 $content,然后需要将其转置为一个数组。例如:

    // An example of a value that is being passed in from the CLI and stored as $content
    $content = "['div']['div'][0]['h2']['a']";

为了澄清,$content 然后作为函数参数传入,用于从实际结果集中提取值。换句话说,我收到来自 API 的响应,$content 是我需要从响应中提取的值的路径。例如,实现的硬编码版本如下所示:

    $result = $report['div']['div'][0]['h2']['a'];

现在,$result 包含我需要处理的值。但是,我正在尝试使这种动态化,因此每次添加新数据源以检查报告时,我都不会重复自己。目前,我有 4 个函数,每个函数都有指向所需结果的硬编码路径;目标是让我可以传入一个包含所需值的路径的参数并重构我的代码,这样我就只有一个函数接受值的路径作为参数。

我希望澄清最终目标以及为什么我只引用键而不是值。

无论如何,回到手头的问题。我尝试了以下不同的变体:

    // Attempting to parse the string into an array
    $arr = explode("]", trim(str_replace("[","",$content), "]"));

这会产生以下数组:

    array (size=5)
      0 => string ''div'' (length=5)
      1 => string ''div'' (length=5)
      2 => string '0' (length=1)
      3 => string ''h2'' (length=4)
      4 => string ''a'' (length=3)

但是,我需要将数组格式化如下:

    $array = ['div']['div'][0]['h2']['a']

我尝试对$arr 执行foreach($array as $element) 并为每个元素执行array_push,但结果与$arr 相同。

如何遍历字符串并将其解析为数组?此外,我需要 0 保留为索引,而不是类型转换为字符串。最后一点,$content 的值每次都会完全不同,所以我需要它非常灵活。唯一保持不变的部分是 [] 将始终封装密钥。

我很想听听其他人将如何解决这个看似微不足道的问题(我已经离开编程几年了,显然忘记的比我愿意承认的要多;))。老实说,我认为 str_replace 和 explode 将为我提供我所期待的结果......

但是,在重新阅读 php.net/explode 文档后,它总是会将每个元素转换为字符串(从而覆盖我的 0 索引),我不知道如何将其转换为嵌套数组,而是一个简单的扁平数组。

我期待您的建议和见解。谢谢。

编辑:

包括使用参数的函数以帮助提供更高的清晰度。

private function yql_check_website($url, $xpath, $content) 

    require_once('../vendor/OAuth.php');

    $statement = "select * from html where url='$url' and xpath='$xpath' ";

    $cc_key  = $this->key;
    $cc_secret = $this->secret;
    $url = "http://query.yahooapis.com/v1/public/yql";
    $args = array();
    $args["q"] = $statement;
    $args["format"] = "json";

    $consumer = new OAuthConsumer($cc_key, $cc_secret);
    $request = OAuthRequest::from_consumer_and_token($consumer, NULL,"GET", $url, $args);
    $request->sign_request(new OAuthSignatureMethod_HMAC_SHA1(), $consumer, NULL);
    $url  = sprintf("%s?%s", $url, OAuthUtil::build_http_query($args));
    $url .= "&env=store://datatables.org/alltableswithkeys";
    $ch = curl_init();
    $headers = array($request->to_header());
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
    $rsp = curl_exec($ch);
    $report = json_decode($rsp, true);

    // Dynamically inspect the $report object for the xpath content
    $result = $report . $content;

    unset($report);

    return $result;

所以,$report 包含整个 API 响应,但我唯一需要的是 $report['div']['div'][0]['h2']['a'] 中提供的内容(至少对于这个示例,我正在抓取的每个报告的路径都不同) .因此,我尝试将命令行参数转换为数组的原因是,它可以在上面调用 $content 的代码中使用,以便导航 API 的响应并从该段返回值。

我希望这更有意义。而且,如果有更好的方法来实现这一最终目标,请随时提及。我可能采取了错误的方法...

【问题讨论】:

$array = ['div']['div'][0]['h2']['a'] 没有意义。你有一堆钥匙,但没有价值。 你想让你的 $array 像:$array[0] = ['div'], $array[1] = ['div'], $array[2] = ['0']...? @meager,我已经更新了问题以澄清为什么我只引用键。 @DroBuddy,我不明白,你的字符串是什么样的? @Akshat,不完全是。它确实是 API 响应的路径,因此我需要将其格式化为 ['div']['div'][0]['h2']['a'] 以便访问 ['a'] 的值。 【参考方案1】:

Laravel 有一些数组访问方法,提供对数组的“点”访问,包括 array_get。方法原型如下所示:

function array_get(array $array, string $key, mixed $default = null)

所以,在你的情况下,你可以写:

$results = array_get($report, "div.div.0.h2.a");

【讨论】:

【参考方案2】:

这是你想要的吗?

$str = "['div']['div'][0]['h2']['a']";
$str = preg_split('/]\[/', substr(str_replace("'", "", $str), 1, -1));
print_r($str);

Array (
    [0] => div 
    [1] => div 
    [2] => 0 
    [3] => h2
    [4] => a 
)

【讨论】:

这很接近,但我需要它是多维的,所以它就像 array( 'div' => array ( 'div' => 'array( "0" => array( "h2 " => array("a") ) ) 。但是,这让我很好地了解了如何去做。【参考方案3】:

你可以在这里使用 preg_match_all..

$content = "['div']['div'][0]['h2']['a']";  
$expression = /\['([a-zA-Z0-9]+)\']/;
$results = preg_match_all( $expression, $content, $matches );
print_r( $matches );

如果你必须让数组像你所说的那样,你可以做这样的事情(对于初学者来说 - 这有点难看,虽然它是......)

// array( ['div']['div'][0]['h2']['a']
// visualizing...
// array( 'div' => array ( 'div' => 'array( "0" => array( "h2" => array( "a") ) ) ) );

function createDepth( $source, $currentKey, $nextDepth = null ) 
  if( !is_array( $nextDepth ) ) 
    $source[] = array( $currentKey => $nextDepth );
   else 
    $nextKey = array_shift( $nextDepth );
    $source[] = createDepth( array( $currentKey => array() ), $nextKey, $nextDepth );
  
  return source;

// Edit: doh, unset the first key..
unset( $matches[0] );

// Continue from here.
$currentKey = array_shift( $matches );
$holder = array();
$final = createDepth( $holder, $currentKey, $matches);
print_r( $final );

注意:以上所有内容均未经测试...

【讨论】:

我会试一试,然后告诉你结果如何。谢谢,乔纳森。 嗯,最终返回了Array ( [0] => Array ( [0] => ['div'] [1] => ['div'] [2] => ['a'] ) [1] => Array ( [0] => div [1] => div [2] => a ) ),但我认为你在这里有所作为。我将尝试使用preg_match_all,看看是否可以调整表达式以提供我正在寻找的结果。感谢您为我指明了一个坚实的方向。如果我能得到它,我很乐意接受这个作为答案。 酷。请务必查看我编辑的答案...创建了一个递归函数来构建它。虽然它未经测试(我在编辑器中构建了它,并且在一年多的时间里没有真正编写过 PHP 代码,呵呵) 有趣...你说得对,这有点难看,但似乎有道理。我会试一试,看看我能做些什么。再次感谢。

以上是关于PHP:将字符串转换为嵌套数组的主要内容,如果未能解决你的问题,请参考以下文章

使用嵌套数组将 JSON 转换为逗号分隔的字符串

将嵌套数组转换为嵌套 html 块的递归 php 函数

PHP在连接键时将嵌套数组转换为单个数组?

Ruby:将String转换为嵌套数组的Integer值

php中有没有将数组的值转换为字符串的函数

如何使用 PHP 将 JSON 字符串数据转换为数组?