2015-05-02 4 views
1

Я хотел бы разобрать короткий код в массив через «preg_split».preg_split атрибуты shortcode в массив

Это пример шорткод:

 
[contactform id="8411" label="This is \" first label" label2='This is second \' label'] 

, и это должно быть результатом массива:

 
Array 
(
    [id] => 8411 
    [label] => This is \" first label 
    [label2] => This is second \' label 
) 

У меня есть это регулярное выражение:

 
$atts_arr = preg_split('~\s+(?=(?:[^\'"]*[\'"][^\'"]*[\'"])*[^\'"]*$)~', trim($shortcode, '[]')); 

К сожалению, это работает только, если есть без вылета котировок \' или \".

Thx заранее!

+0

'preg_split' не путь, используйте' preg_match_all' и '\ G' якорь, если вам нужно, чтобы обеспечить примыкание результатов. –

+0

Я не знаю, дал ли Казимир и Ипполит правильный ответ. Но это очень сложная проблема. Я решил это, используя формат json для параметров в аналогичной ситуации. – splash58

ответ

0

Использование preg_split не всегда удобно или подходит, особенно если вам приходится иметь дело с экранированными кавычками. Таким образом, лучший подход состоит в использовании preg_match_all, пример:

$pattern = <<<'EOD' 
~ 
(\w+) \s*= 
(?| 
    \s* "([^"\\]*(?:\\.[^"\\]*)*)" 
    | 
    \s* '([^'\\]*(?:\\.[^'\\]*)*)' 
# | uncomment if you want to handle unquoted attributes 
# ([^]\s]*) 
) 
~xs 
EOD; 

if (preg_match_all($pattern, $yourshortcode, $matches)) 
    $attributes = array_combine($matches[1], $matches[2]); 

Шаблон использует филиальную функцию сброса (?|...(..)...|...(...)..), который дает один и тот же номер (а) к группам захвата для каждой отрасли.

Я говорил о якоре \G в своем комментарии, этот якорь преуспевает, если текущая позиция сразу после последнего матча. Это может быть полезно, если вы хотите проверить синтаксис своего короткого кода от начала до конца в одно и то же время (в противном случае это абсолютно бесполезно). Пример:

$pattern2 = <<<'EOD' 
~ 
(?: 
    \G(?!\A) # anchor for the position after the last match 
      # it ensures that all matches are contiguous 
    | 
    \[(?<tagName>\w+) # begining of the shortcode 
) 
    \s+ 
    (?<key>\w+) \s*= 
    (?| 
     \s* "(?<value>[^"\\]*(?:\\.[^"\\]*)*)" 
     | 
     \s* '([^'\\]*(?:\\.[^'\\]*)*') 
    # | uncomment if you want to handle unquoted attributes 
    # ([^]\s]*) 
    ) 
(?<end>\s*+]\z)? # check that the end has been reached 
~xs 
EOD; 

if (preg_match_all($pattern2, $yourshortcode, $matches) && isset($matches['end'])) 
    $attributes = array_combine($matches['key'], $matches['value']); 
+0

Этот ответ решил проблему для моего списка проблем ... Подход с ** preg_match_all ** действительно классный, thx – Mariyo