【问题标题】:Divide string into associtive array将字符串划分为关联数组
【发布时间】:2016-08-06 15:00:06
【问题描述】:

我有一个字符串:

$string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

我想把这个字符串拆分成一个关联数组。

$result['Q)'] = 'EHAA/QARLT/I /NBO/E /000/999/5155N00430E073';
$result['A)'] = 'EHAA';
$result['B)'] = '1605260001';
$result['C)'] = '1608260900 EST';

等等

我设法将它放入一个数组中:

$result = preg_split("/.\)/", $string);

它给了我一个数组,但我需要键是 'a)', 'b)' 等。

谁能帮我解决这个问题?

【问题讨论】:

  • 最好退后一步看看你是如何创建该字符串的,也许那是一个更好的地方进行更改

标签: php arrays split associative-array preg-split


【解决方案1】:

使用具有特定正则表达式模式的preg_match_all 函数(命名子掩码)和array_combine 函数(获取相应的键/值对)的解决方案:

$string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

preg_match_all("/(?<k>[A-Z]\)) (?<v>.+?)(?= [A-Z]\)|$)/", $string, $matches);

// 'k'/'v' are key/value
$result = array_combine($matches['k'], $matches['v']);

print_r($result);

输出:

Array
(
    [Q)] => EHAA/QARLT/I /NBO/E /000/999/5155N00430E073
    [A)] => EHAA
    [B)] => 1605260001
    [C)] => 1608260900 EST
    [E)] => REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.
)

【讨论】:

  • 你的方式显然是最好的。请注意,您可以删除选项 PREG_SET_ORDER 并在不使用 foreach 的情况下构建结果,如下所示:$result = array_combine($matches['k'], $matches['v']);
  • @CasimiretHippolyte,感谢您的有用提示。我已经简化了答案
【解决方案2】:

另一个愚蠢的解决方案,因为为什么不呢。

  $string = 'A0695/16 NOTAMN Q) EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 A) EHAA B) 1605260001 C) 1608260900 EST E) REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE.';

  $foo = preg_split('/([A-Z]\)) /', $string, 0, PREG_SPLIT_DELIM_CAPTURE);
  $ret = [];
  foreach (range(1, count($foo) - 1, 2) as $i)
  {
    $ret[$foo[$i]] = $foo[$i + 1];
  }
  print_r($ret);

打印:

Array (
    [Q)] => EHAA/QARLT/I /NBO/E /000/999/5155N00430E073 
    [A)] => EHAA 
    [B)] => 1605260001 
    [C)] => 1608260900 EST 
    [E)] => REF AIP NETHERLANDS ENR 3.2 UT601 ADD TO ROUTE REMARKS: NOT AVBL FOR TRAFFIC DEP/ARR ETNG, EDDK AND ETNN DURING THE OPENING OF EHEH 0600-2300 (0500-2200). THESE FLIGHTS WILL HAVE TO REROUTE. )

【讨论】:

    【解决方案3】:

    幻想多于效率,但它确实有效:

    $p = preg_split('~(?<!\S)([A-Z]\))\s+~', $string, -1, PREG_SPLIT_DELIM_CAPTURE);
    $result = [];
    if (count($p) > 1) {
        unset($p[0]);
        while($p) { 
            $result[array_shift($p)] = array_shift($p);
        }
    }
    
    print_r($result);
    

    【讨论】:

      猜你喜欢
      • 2018-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-06-06
      • 1970-01-01
      • 2019-06-26
      • 1970-01-01
      相关资源
      最近更新 更多