我希望有人可以提供帮助。
我有一个字符串如下
$string = 'latitude=46.6781471,longitude=13.9709534,options=[units=auto,lang=de,exclude=[hourly,minutely]]';
现在我正在尝试的是从每个键值对中创建一个数组但是使用regex为preg_match_all()严重失败
目前我的尝试没有给出所需的结果,创建了key =>只要没有括号,值对就可以工作,但是如果键包含示例中括号内的键/值对,我完全不知道如何实现多维数组。
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
)
)
如果我能从给定的字符串中实现这一点,我将不胜感激。
答案 0 :(得分:2)
正则表达式不是处理递归匹配的正确工具。您可以编写解析器而不是正则表达式(或使用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 = [hourly,minutely]变为exclude =&gt; hourly,minutely和not exclude =&gt; array(每小时,每分钟))。我认为这与您的格式不一致,我在编写解析器时考虑到了“正确”的版本。
答案 1 :(得分:0)
如果您不想要解析器,您也可以尝试使用此代码。它将您的字符串转换为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);