PHP:将字符串转换为数组

6

如何将字符串转换为数组?

以下是字符串:

$string = "12&Shoes&28&Jewelry&30&Watch&96&Beauty&98&Kids&Baby";

需要输出:

 array{
        [12] => 'Shoes',
        [28] => 'Jewelry',
        [30] => 'Watch',
        [96] => 'Beauty',
        [98] => 'Kids&Baby'
    }

有人能建议我如何使用 PHP 函数(例如 preg_match,preg_match_all 等)将其转换吗?同时代码应该简短。

1
你尝试过什么吗? - manian
http://php.net/manual/en/function.explode.php - Hackerman
将我的explode结果转化为单数组,例如Array([0] => 12 [1] => 鞋子 [2] => 28 [3] => 珠宝 [4] => 30 [5] => 手表 [6] => 96 [7] => 化妆品 [8] => 98 [9] => 儿童 [10] => 婴儿) - R P
这将非常困难,因为该字符串没有遵循任何模式。也许你可以识别整数和字符串来进行分割。 - manian
1
由于字符串包含“Kids&Baby”,我不确定迄今为止的任何答案是否会给出精确结果。 - manian
显示剩余7条评论
6个回答

3

我知道您要求使用正则表达式,但如果有更简单的方法,我喜欢用其他方式。

$string = "12&Shoes&28&Jewelry&30&Watch&96&Beauty&98&Kids&Baby&Try";
$array = explode('&', $string);
$total = count($array);
for ($i = 0; $i < $total; $i++) {
  if (is_numeric($array[$i])) {
   $result[$array[$i]] = '';
   $lastIndex = $array[$i];
  } else {
    if ($result[$lastIndex] == ''){
       $result[$lastIndex] .= $array[$i];
    } else {
        $result[$lastIndex] .= '&' . $array[$i];
    }
  }
}
var_dump($result);

1
我的第一个想法,但不行是因为“儿童与婴儿”这个原因。 - mighTY
1
@mighTY 完成了! ;) - capcj
太好了,完成了。我们能优化它吗? - R P
你能解释一下你是如何修复Kids&Baby的问题的吗? :D - Adnan
@skunkhaze,之前的代码很复杂,我进行了简化,请审核一下。我正在工作中,如果不能做到最好请见谅。 - capcj
显示剩余3条评论

1
请尝试使用preg_split和PREG_SPLIT_DELIM_CAPTURE一起获取被拆分的项。
$string = "12&Shoes&28&Jewelry&30&Watch&96&Beauty&98&Kids&Baby";

$array = preg_split("/(\d+)/", $string, -1, PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
foreach($array AS $key => $val) {
   if($key%2) continue;
   $result[$val] = trim($array[$key+1], '&');
}

1
尝试下一个:

$list = array();

// $tmp = explode('&', $string); - not suitable coz of 'Value&Value' existence 
preg_match_all('/\d+|[a-z&]+/i', $string, $tmp);
foreach ($tmp[0] as $i => $value) {
    // 0, 2, ... elements are the keys
    if ($i%2 === 0) {
        $key = $value;
    // 1, 3 ... values
    } else {
        $list[$key] = trim($value, '&');
    }
}

甚至更短的版本:

preg_match_all('/(\d+)\&([a-z&]+[^\&0-9])/i', $string, $tmp);
$list = array_combine($tmp[1], $tmp[2]);

结果:

var_dump($list);

array(5) {
  [12] => string(5) "Shoes"
  [28] => string(7) "Jewelry"
  [30] => string(5) "Watch"
  [96] => string(6) "Beauty"
  [98] => string(9) "Kids&Baby"
}

感谢回复和尝试。代码给了我警告,如下:
  • 警告:trim()期望参数1为字符串,在D:\xampp\htdocs\test\index.php的第11行中给出数组。
  • 警告:非法偏移类型在D:\xampp\htdocs\test\index.php的第11行中给出。
- R P
@RP,在上次编辑之前是正确的(foreach ($tmp -> foreach ($tmp[0])。 - FieryCat
更短的代码如下:preg_match_all('/(\d+)\&([a-z&]+[^\&0-9])/i', $string, $tmp); $list = array_combine($tmp[1], $tmp[2]); - FieryCat

0

这是我对 @FieryCat 代码片段的改进。

为了适应 Kids&Baby,只需使“值”组件在紧跟字母后立即包含 & 成为可选项。

代码: (演示)

$string = "12&Shoes&28&Jewelry&30&Watch&96&Beauty&98&Kids&Baby";

var_export(
    preg_match_all(
        '/(\d+)&([a-z]+(?:&[a-z]+)?)/i',
        $string,
        $m
    )
    ? array_combine($m[1], $m[2])
    : []
);

输出:

array (
  12 => 'Shoes',
  28 => 'Jewelry',
  30 => 'Watch',
  96 => 'Beauty',
  98 => 'Kids&Baby',
)

0

我删除了之前的回答,因为我建议使用parse_str,但我没有正确阅读问题。

一个解决方案可能是使用preg_match_all。 唯一的问题是,我无法过滤掉每个值末尾的最后一个&。再次尝试弄清楚正则表达式不匹配的工作原理 :)

注意!如果您的值包含数字,则此方法将无法正常工作!

php > preg_match_all('/(?P<key>[0-9]+)&(?P<values>[^0-9]+)/i', $string, $matches);
php > var_dump($matches);
array(5) {
  [0]=>
  array(5) {
    [0]=>
    string(9) "12&Shoes&"
    [1]=>
    string(11) "28&Jewelry&"
    [2]=>
    string(9) "30&Watch&"
    [3]=>
    string(10) "96&Beauty&"
    [4]=>
    string(12) "98&Kids&Baby"
  }
  ["key"]=>
  array(5) {
    [0]=>
    string(2) "12"
    [1]=>
    string(2) "28"
    [2]=>
    string(2) "30"
    [3]=>
    string(2) "96"
    [4]=>
    string(2) "98"
  }
  [1]=>
  array(5) {
    [0]=>
    string(2) "12"
    [1]=>
    string(2) "28"
    [2]=>
    string(2) "30"
    [3]=>
    string(2) "96"
    [4]=>
    string(2) "98"
  }
  ["values"]=>
  array(5) {
    [0]=>
    string(6) "Shoes&"
    [1]=>
    string(8) "Jewelry&"
    [2]=>
    string(6) "Watch&"
    [3]=>
    string(7) "Beauty&"
    [4]=>
    string(9) "Kids&Baby"
  }
  [2]=>
  array(5) {
    [0]=>
    string(6) "Shoes&"
    [1]=>
    string(8) "Jewelry&"
    [2]=>
    string(6) "Watch&"
    [3]=>
    string(7) "Beauty&"
    [4]=>
    string(9) "Kids&Baby"
  }
}

非常抱歉,我扫描您的字符串太快了,没有注意到它不是有效的参数=值组合,就像您在URL中使用的那样。因此,我的解决方案将无法工作。如果您的字符串看起来像这样:“$string =“12 = Shoes&28 = Jewelry&30 = Watch&96 = Beauty&98 = Kids&Baby””,它将起作用。 - Ali Alwash

-1

试试这个:

function trim_custom($item){
  return trim($item,'&');
}

$string = "12&Shoes&28&Jewelry&30&Watch&96&Beauty&98&Kids&Baby";
$values = array_filter( explode(",",preg_replace("/[^a-zA-Z-&]+/", ",", $string)) );
$values = array_map('trim_custom',$values);
$keys = array_filter ( explode(",",preg_replace("/[^0-9]+/", ",", $string)) );

$list = array_combine($keys,$values);

输出:

print_r($list);

Array
(
    [12] => Shoes
    [28] => Jewelry
    [30] => Watch
    [96] => Beauty
    [98] => Kids&Baby
)

1
Kids&Baby是一个值。 - Adnan
@Ali Hesari 谢谢。但是最后的“Kids&Bab”会有问题。 - R P
@RP 我已经修复了函数。 - Ali Hesari

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接