Разбор списка атрибутов / значений в PHP

Учитывая строку с парами атрибутов / значений, например,

attr1="some text" attr2 = "some other text" attr3= "some weird !@'#$\"=+ text" 

цель состоит в том, чтобы проанализировать его и вывести ассоциативный массив, в этом случае:

 array('attr1' => 'some text', 'attr2' => 'some other text', 'attr3' => 'some weird !@\'#$\"=+ text') 

Обратите внимание на несогласованное расстояние вокруг равных знаков, экранированную двойную кавычку на входе и экранированную одиночную кавычку в выходном файле.

Solutions Collecting From Web of "Разбор списка атрибутов / значений в PHP"

Попробуйте что-то вроде этого:

 $text = "attr1=\"some text\" attr2 = \"some other text\" attr3= \"some weird !@'#$\\\"=+ text\""; echo $text; preg_match_all('/(\S+)\s*=\s*"((?:\\\\.|[^\\"])*)"/', $text, $matches, PREG_SET_ORDER); print_r($matches); 

который производит:

 attr1="some text" attr2 = "some other text" attr3= "some weird !@'#$\"=+ text" Array ( [0] => Array ( [0] => attr1="some text" [1] => attr1 [2] => some text ) [1] => Array ( [0] => attr2 = "some other text" [1] => attr2 [2] => some other text ) [2] => Array ( [0] => attr3= "some weird !@'#$\"=+ text" [1] => attr3 [2] => some weird !@'#$\"=+ text ) ) 

И короткое объяснение:

 (\S+) // match one or more characters other than white space characters // > and store it in group 1 \s*=\s* // match a '=' surrounded by zero or more white space characters " // match a double quote ( // open group 2 (?:\\\\.|[^\\"])* // match zero or more sub strings that are either a backslash // > followed by any character, or any character other than a // > backslash ) // close group 2 " // match a double quote 

EDIT: это регулярное выражение не выполняется, если значение заканчивается attr4="something\\" например attr4="something\\"

Я не знаю PHP, но поскольку регулярное выражение будет по существу одинаковым на любом языке, так я сделал это в ActionScript:

 var text:String = "attr1=\"some text\" attr2 = \"some other text\" attr3= \"some weird !@'#$\\\"=+ text\""; var regex:RegExp = /\s*(\w+)\s*=\s*(?:"(.*?)(?<!\\)")\s*/g; var result:Object; while(result = regex.exec(text)) trace(result[1] + " is " + result[2]); 

И я получил следующее:

attr1 – некоторый текст
attr2 – это другой текст
attr3 – это нечто странное! @ '# $ \ "= + текст