如何将属性字符串解析为 PHP 中的数组?
How can I parse an attribute string to an array in PHP?
在PHP中,我需要解析字符串中的参数,如:
{keyword name1=val1 name2='val2' name3="val3"}
最后得到一个像这样的数组:
{
name1 => "val1",
name2 => "val2",
name3 => "val3"
}
每个值可能会或可能不会被引用,并且可以使用单引号或双引号引用。此外,值可能包含 space、标点符号,甚至反引号。例如,这可能是一个有效的属性:
name1="Isn't this OK?"
理想情况下,它还允许在值内使用转义引号,但这只是一个额外的好处。我希望有一个功能,就像 HTML
浏览器解析器在解析 HTML
标签上的属性时所做的那样。
我的第一个想法是一次逐个检查字符串中的一个字符,检查等号后面的字符是否是引号,然后寻找下一个匹配的引号。但这似乎很乏味,而且并不是解析字符串的最有效方法。
我看到的使用正则表达式的例子让我难以理解,不可读,而且太复杂以至于我无法维护。
我也看过使用 DOMdocument
的示例,但是当值中有 space 或逗号时,它们无法正确解析。
我需要在 PHP
中执行此操作,而不是 Javascript
。
是否有函数(在 PHP
中)如果我只传递属性部分,它将 return 数组?
使用像 addslashes()
这样的函数来转义引号。
我知道你说过你不喜欢正则表达式解决方案,但我还是要给你一个 :) 至少人们可以与这里不使用正则表达式的任何其他可能答案进行比较。
您可以在此处查看并使用正则表达式:
https://regex101.com/r/cT6bT0/1。
这将尝试在右上角向您解释正则表达式 - 标题为 "Explanation".
代码:
// For demonstration is use heredoc for input string so that i escape of quotes is not necesarry.
$input = <<<END
{keyword name1=val1 name2='val2' name3="val3" name4="Isn't this OK?" name5=okay name6='Isn\'t' name7="A \"quote\""}
END;
$re = "/(?:\s*(\w+)\s*=\s*(?:'((?:[^'\\]|\\')*)'|\"((?:[^\"\\]|\\\")*)\"?|(\w+)))/";
preg_match_all($re, $input, $parts, PREG_SET_ORDER);
$result=[];
foreach ($parts as $part) {
$result[$part[1]] = stripslashes($part[2] ? $part[2] : ($part[3] ? $part[3] : $part[4])) . "\n";
}
print_r($result);
输出:
Array
(
[name1] => val1
[name2] => val2
[name3] => val3
[name4] => Isn't this OK?
[name5] => okay
[name6] => Isn't
[name7] => A "quote"
)
在PHP中,我需要解析字符串中的参数,如:
{keyword name1=val1 name2='val2' name3="val3"}
最后得到一个像这样的数组:
{
name1 => "val1",
name2 => "val2",
name3 => "val3"
}
每个值可能会或可能不会被引用,并且可以使用单引号或双引号引用。此外,值可能包含 space、标点符号,甚至反引号。例如,这可能是一个有效的属性:
name1="Isn't this OK?"
理想情况下,它还允许在值内使用转义引号,但这只是一个额外的好处。我希望有一个功能,就像 HTML
浏览器解析器在解析 HTML
标签上的属性时所做的那样。
我的第一个想法是一次逐个检查字符串中的一个字符,检查等号后面的字符是否是引号,然后寻找下一个匹配的引号。但这似乎很乏味,而且并不是解析字符串的最有效方法。
我看到的使用正则表达式的例子让我难以理解,不可读,而且太复杂以至于我无法维护。
我也看过使用 DOMdocument
的示例,但是当值中有 space 或逗号时,它们无法正确解析。
我需要在 PHP
中执行此操作,而不是 Javascript
。
是否有函数(在 PHP
中)如果我只传递属性部分,它将 return 数组?
使用像 addslashes()
这样的函数来转义引号。
我知道你说过你不喜欢正则表达式解决方案,但我还是要给你一个 :) 至少人们可以与这里不使用正则表达式的任何其他可能答案进行比较。
您可以在此处查看并使用正则表达式: https://regex101.com/r/cT6bT0/1。 这将尝试在右上角向您解释正则表达式 - 标题为 "Explanation".
代码:
// For demonstration is use heredoc for input string so that i escape of quotes is not necesarry.
$input = <<<END
{keyword name1=val1 name2='val2' name3="val3" name4="Isn't this OK?" name5=okay name6='Isn\'t' name7="A \"quote\""}
END;
$re = "/(?:\s*(\w+)\s*=\s*(?:'((?:[^'\\]|\\')*)'|\"((?:[^\"\\]|\\\")*)\"?|(\w+)))/";
preg_match_all($re, $input, $parts, PREG_SET_ORDER);
$result=[];
foreach ($parts as $part) {
$result[$part[1]] = stripslashes($part[2] ? $part[2] : ($part[3] ? $part[3] : $part[4])) . "\n";
}
print_r($result);
输出:
Array
(
[name1] => val1
[name2] => val2
[name3] => val3
[name4] => Isn't this OK?
[name5] => okay
[name6] => Isn't
[name7] => A "quote"
)