我正在尝试在接下来的两周内完成一个PHP应用程序,我只是无法弄清楚正则表达式来解析一些属性字符串。
我得到的格式类似于这个字符串的随机字符串:
KeyName1="KeyValue1" KeyName2='KeyValue2'
单个字符串中可能有任意数量的键值对,并且值可以用单引号'或双引号“分隔在一个字符串中string(但它们总是被分隔)。
键值可以是任何长度并包含任何字符,除了双引号不能在双引号内,单引号不能在单引号内,但双引号可以在单引号内,单引号可以是在双引号内。
键值对之间可以有任意数量的空格,键名和等号之间可以有任意数量的空格,等号和引号键可以起始键值。
我需要将字符串转换为如下所示的数组:
$arrayName["KeyName1"] = "KeyValue1"
$arrayName["KeyName2"] = "KeyValue2"
等
我很确定它可以用正则表达式完成,但我所有的尝试都失败了,我需要一些帮助(实际上有很多帮助:-)来完成这项工作,我希望这里有一些很棒的人可以提供帮助或至少让我开始。
答案 0 :(得分:7)
当然,没问题。让我们分解一下:
\w+\s*=\s*
匹配一个字母数字关键字,后跟一个等号(可能被空格包围)。
"[^"]*"
匹配一个开头的双引号,后跟除了另一个双引号之外的任意数量的字符,然后是一个(结束)双引号。
'[^']*'
对于单引号字符串,也是如此。
使用捕获组((...)
)将其与简单的替换(|
)相结合,可以为您提供
(\w+)\s*=\s*("[^"]*"|'[^']*')
在PHP中:
preg_match_all('/(\w+)\s*=\s*("[^"]*"|\'[^\']*\')/', $subject, $result, PREG_SET_ORDER);
使用一系列匹配填充$result
。 $result[n]
将包含n
匹配的详细信息,其中
$result[n][0]
是整场比赛$result[n][1]
包含关键字$result[n][2]
包含值(包括引号)修改强>
要匹配没有引号的值部分,无论使用何种引号,都需要使用positive lookahead assertion的稍微复杂的正则表达式:
(\w+)\s*=\s*(["'])((?:(?!\2).)*)\2
在PHP中:
preg_match_all('/(\w+)\s*=\s*(["\'])((?:(?!\2).)*)\2/', $subject, $result, PREG_SET_ORDER);
结果
$result[n][0]
:整场比赛$result[n][1]
:keyword $result[n][2]
:引用字符$result[n][3]
:value <强>解释强>
(["']) # Match a quote (--> group 2)
( # Match and capture --> group 3...
(?: # the following regex:
(?!\2) # As long as the next character isn't the one in group 2,
. # match it (any character)
)* # any number of times.
) # End of capturing group 3
\2 # Then match the corresponding quote character.
答案 1 :(得分:2)
Tim Pietzcker的一个小变种:
preg_match_all('/(\w+)\s*=\s*(?|"([^"]*)"|\'([^\']*)\')/', $subject, $result, PREG_SET_ORDER);
然后你有$result[n][2]
包含没有引号的值。
答案 2 :(得分:1)
如何
您可以使用back references获取所需内容,请参阅此模式:
/\b(\w+)\s*=\s*('|\")(.*)\2/U
\b
是字边界,(\w
)捕获密钥,然后是=
,(捕获)撇号或引号,后跟任何内容,直到\2
,这是第二个被捕获的括号(撇号或引号)。 U
修饰符表示ungreedy evaluation。
示例强>
// match the key-value pairs
$text = "mykey1= \"my'value1'\" mykey2 = 'my\"value2' mykey3=\"my value3\"";
preg_match_all("/\b(\w+)\s*=\s*('|\")(.*)\\2/U",$text,$matches);
// produce result in format you need
$result = array();
for($i=0; $i<count($matches[0]); ++$i) {
$result[$matches[1][$i]] = $matches[3][$i];
}
<强>结果强>
Array
(
[mykey1] => my'value1'
[mykey2] => my"value2
[mykey3] => my value3
)
答案 3 :(得分:0)
想要输出:
$arrayName["KeyName1"] = "KeyName1"
$arrayName["KeyName2"] = "KeyName2"
我希望你的意思是:
$arrayName["KeyName1"] = "KeyValue1"
$arrayName["KeyName2"] = "KeyValue2"
function paramStringToArray($string) {
$array = array_filter(explode(' ', $string));
$result = array();
foreach($array as $value) {
$data = explode('=', $value);
$data[1] = trim($data[1],'"');
$data[1] = trim($data[1],'\'');
$result[$data[0]] = $data[1];
}
return $result;
}
$string = 'KeyName1="KeyValue1" KeyName2=\'KeyValue2\'';
echo '<pre>';
var_dump(paramStringToArray($string));
echo '</pre>';
输出:
array(2) {
["KeyName1"]=> "KeyValue1"
["KeyName2"]=> "KeyValue2"
}