Reputation: 141
I don't know what the title of the question should be. This something logical and what I lack is the same.
I have a string in the format [CONST att1="value1" att2="value2"]
and created a regex that was working fine. But certain conditions made this regex wrong.
$data = preg_split('/(?<=\")\s/', $replace_str[1]);
foreach ($data as $index_val => $exp_data) {
if(!empty($exp_data)){
$attributes = explode('=',$exp_data);
if(count($attributes) > 0){
$index = strtolower(str_replace(array("'", "\""), "", trim($attributes[0])));
$item_value = str_replace(array("'", "\""), "", trim($attributes[1]));
$item_value = $attributes[1];
$array_data[$index] = $item_value;
}
}
}
Then using the array to get key value. But in some instance, say if the format is like the one below
[CONST att1="value1" att2= "value2"]
the exploded variable contains "value2"
(notice the prefixed space). What i want is "value2"
.
So since my format is similar to that of WordPress shortcode referred shortcode.php file in WordPress and found @[<>&/\[\]\x00-\x20=]@
inside the file. But I am unable to understand or make it work.
I need to access value1
and value2
as clean data. i.e, without spaces, single and double quotes at the start and end. Also if the order of the att1
and att2
is changed, it should work.
[CONST att2="value2" att1="value1"]
Should output:
array(att1=>value1,att2=>value2)
Upvotes: 1
Views: 598
Reputation: 626920
I suggest collecting keys and values in the shortcode string using a matching regex with preg_match_all
like
'~(?:\G(?!\A)\s+|^\[\w+\s+)\K([^\s=]*)\s*=\s*"([^"]*)"~'
See the regex demo.
Details
(?:\G(?!\A)\s+|^\[\w+\s+)
\K
- match reset operator([^\s=]*)
- Group 1 (attribute name): 0+ chars other than whitespace and =
\s*=\s*
- a =
enclosed with 0+ whitespaces"
- a double quotation mark([^"]*)
- Group 2 (attribute value inside quotes): any 0+ chars other than "
"
- a double quotation markAfter you get an array of matches you will have to build your associative array "manually" like
$s = '[CONST att1="value1" att2="value2"]';
preg_match_all('/(?:\G(?!\A)\s+|^\[\w+\s+)\K(\w+)\s*=\s*"([^"]*)"/', $s, $array_data, PREG_SET_ORDER, 0);
$res = [];
foreach ($array_data as $kvp) {
$res[$kvp[1]] = $kvp[2];
}
print_r($res);
// -> Array ( [att1] => value1 [att2] => value2 )
See the PHP demo.
Another way of processing the matches (demo):
if (preg_match_all('/(?:\G(?!\A)\s+|^\[\w+\s+)\K(\w+)\s*=\s*"([^"]*)"/', $s, $array_data)) {
array_shift($array_data);
print_r(array_combine($array_data[0], $array_data[1]));
}
Upvotes: 1