提取字符串的部分(PHP)

时间:2015-10-22 02:13:58

标签: php string

我有一个如下字符串。

$str = "ENGINE=InnoDB 
        DEFAULT CHARSET=utf8 
        COLLATE=utf8_unicode_ci 
        COMMENT='Table comment'";

我需要解析字符串中的键/值对,并将它们与下面数组中的键/值对结合起来...

$arr = array("ENGINE" => "InnoDB",
             "DEFAULT CHARSET" => "utf8",
             "COLLATE" => "utf8_unicode_ci",
             "COMMENT" => "'Table comment'");

这里字符串部分的顺序可以不同。

示例:

$str = "ENGINE=InnoDB
        COMMENT='Table comment'
        COLLATE=utf8_unicode_ci
        DEFAULT CHARSET=utf8";

3 个答案:

答案 0 :(得分:6)

您应该使用preg_match_all()并让PHP以您希望的格式从那里构建输出。这是PHP中的一个工作示例。还有regex statement

<?php
    $str = "ENGINE=InnoDB COMMENT='Table comment' COLLATE=utf8_unicode_ci DEFAULT CHARSET=utf8";
    preg_match_all("/([\w ]+)=(\w+|'(?:[^'\\\]|\\.)+')\s*/",$str,$matches,PREG_SET_ORDER);
    $out = [];
    foreach($matches as $match) {
        $out[$match[1]] = $match[2];
    }
    var_dump($out);
?>

结果:

array(4) {
  ["ENGINE"]=>
  string(6) "InnoDB"
  ["COMMENT"]=>
  string(15) "'Table comment'"
  ["COLLATE"]=>
  string(15) "utf8_unicode_ci"
  ["DEFAULT CHARSET"]=>
  string(4) "utf8"
}

正则表达式的解释

([\w ]+) // match one or more word characters (alpha+underscore+space)
= // match equals sign
  (
      \w+ // match any word character
   | // or
      ' // match one exact quote character
      (?:[^'\\]|\\.)+ // match any character including escaped quotes
      ' // match one exact quote character
   )
\s* // match any amount of whitespace until next match

答案 1 :(得分:1)

字符串看起来像ini - 文件。使用parse_ini_string

$str = "ENGINE=InnoDB DEFAULT 
        CHARSET=utf8 
        COLLATE=utf8_unicode_ci 
        COMMENT='Table comment'";

$data = parse_ini_string($str);
var_dump($data);

array(4) {
   ["ENGINE"]=>
   string(14) "InnoDB DEFAULT"
   ["CHARSET"]=>
   string(4) "utf8"
   ["COLLATE"]=>
   string(15) "utf8_unicode_ci"
   ["COMMENT"]=>
   string(13) "Table comment"
}

答案 2 :(得分:0)

这是一种解释数据的冗长,不优雅的方式(有大量的评论解释)。这可以适用于不同结构的字符串。

<?php

$str = "ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci COMMENT='Table comment'";
$keys = array('ENGINE', 'DEFAULT CHARSET', 'COLLATE', 'COMMENT');

$str_array = explode('=', $str); 
/* result of the above will be
[0] => ENGINE
[1] => InnoDB DEFAULT CHARSET
[2] => utf8 COLLATE
[3] => utf8_unicode_ci COMMENT
[4] => 'Table comment' 
*/

$output = array();
$lastkey = '';

// loop through each split item
foreach ($str_array as $item) {

    // if the item is entirely one of the keys, just remember it as the last key
    if (in_array($item, $keys)) {
        $lastkey = $item;
        continue;
    }

    // check if item like InnoDB DEFAULT CHARSET contains one of the keys
    // if item contains a key, the key will be returned
    // Otherwise, item will be returned
    $result = item_has_a_key($item, $keys);

    if ($result === $item) {
        // if the result is exactly the item, that means no key was found in the item
        // that means, it is the value of the previously found key
        $output[$lastkey] = $item;
    } else {    
        // if the result is not exactly the item, that means it contained one of the keys
        // strip out the key leaving only the value. Assign the value to previously found key
        $output[$lastkey] = trim(str_replace($result, '', $item));

        // remember the key that was found
        $lastkey = $result;
    }
}

print_r($output);
/*
Result:
[ENGINE] => InnoDB
[DEFAULT CHARSET] => utf8
[COLLATE] => utf8_unicode_ci
[COMMENT] => 'Table comment'
*/


// $item can be InnoDB DEFAULT CHARSET
// $keys is the array of keys you have assigned (ENGINE, DEFAULT CHARSET etc.)
// if the item contains one of the keys, the key will be returned
// if the item contains no key, the item will be returned
function item_has_a_key($item, $keys) {
    foreach ($keys as $key) {
        if (strpos($item, $key) !== false) {
            return $key;
        }
    }
    return $item;
}
?>