希望有人能帮忙。
我有一个如下的字符串
$string = 'latitude=46.6781471,longitude=13.9709534,options=[units=auto,lang=de,exclude=[hourly,minutely]]';
现在我要尝试的是创建一个数组的每个键,值对,但严重失败与preg_match_all() regex
目前我的尝试并没有给出预期的结果,只要没有括号,创建键=>值对就可以工作,但我绝对不知道如何实现多维数组,如果键在括号内包含键/值对。
Array (
[0] => Array
(
[0] => latitude=46.6781471,
[1] => longitude=13.9709534,
[2] => options=[units=si,
[3] => lang=de,
)
[1] => Array
(
[0] => latitude
[1] => longitude
[2] => options=[units
[3] => lang
)
.. and so on
最后我想达到的结果如下。
Array (
[latitude] => 46.6781471
[longitude] => 13.9709534
[options] => Array
(
[units] => auto
[exclude] => hourly,minutely
)
)
我很感激任何帮助或例子,我如何能从一个给定的字符串实现这一点。
正则表达式不是处理递归匹配的正确工具。您可以编写解析器而不是正则表达式(或使用JSON,查询字符串,XML或任何其他常用格式):
function parseOptionsString($string) {
$length = strlen($string);
$key = null;
$contextStack = array();
$options = array();
$specialTokens = array('[', ']', '=', ',');
$buffer = '';
$currentOptions = $options;
for ($i = 0; $i < $length; $i++) {
$currentChar = $string[$i];
if (!in_array($currentChar, $specialTokens)) {
$buffer .= $currentChar;
continue;
}
if ($currentChar == '[') {
array_push($contextStack, [$key, $currentOptions]);
$currentOptions[$key] = array();
$currentOptions = $currentOptions[$key];
$key = '';
$buffer = '';
continue;
}
if ($currentChar == ']') {
if (!empty($buffer)) {
if (!empty($key)) {
$currentOptions[$key] = $buffer;
} else {
$currentOptions[] = $buffer;
}
}
$contextInfo = array_pop($contextStack);
$previousContext = $contextInfo[1];
$thisKey = $contextInfo[0];
$previousContext[$thisKey] = $currentOptions;
$currentOptions = $previousContext;
$buffer = '';
$key = '';
continue;
}
if ($currentChar == '=') {
$key = $buffer;
$buffer = '';
continue;
}
if ($currentChar == ',') {
if (!empty($key)) {
$currentOptions[$key] = $buffer;
} else if (!empty($buffer)) {
$currentOptions[] = $buffer;
}
$buffer = '';
$key = '';
continue;
}
}
if (!empty($key)) {
$currentOptions[$key] = $buffer;
}
return $currentOptions;
}
输出如下:
print_r(parseOptionsString($string));
Array
(
[latitude] => 46.6781471
[longitude] => 13.9709534
[options] => Array
(
[units] => auto
[lang] => de
[exclude] => Array
(
[0] => hourly
[1] => minutely
)
)
)
还要注意,对于只有逗号分隔值的数组,您需要一种特殊的语法(exclude=[hour, minuminute]变成exclude=> hour, minuminute,而not exclude=> array(hour, minuminute))。我认为这是你的格式不一致,我写的解析器与"正确"的版本。
如果您不需要解析器,您也可以尝试这段代码。它将字符串转换为JSON并解码为数组。但正如其他人所说,我认为您应该尝试使用JSON的方法。如果你在JavaScript中通过XmlHttpRequest发送这个字符串,那么创建合适的JSON代码来发送并不难。
$string = 'latitude=46.6781471,longitude=13.9709534,options=[units=auto,lang=de,exclude=[hourly,minutely]]';
$string = preg_replace('/([^=,[]s]+)/', '"$1"', $string);
$string = '{' . $string . '}';
$string = str_replace('=', ':', $string);
$string = str_replace('[', '{', $string);
$string = str_replace(']', '}', $string);
$string = preg_replace('/({[^:}]*})/', '|$1|', $string);
$string = str_replace('|{', '[', $string);
$string = str_replace('}|', ']', $string);
$result = json_decode($string, true);
print_r($result);