Я хотел бы проанализировать шорткод в массив через «preg_split».
Это пример шорткода:
[contactform id = "8411" label = "Это \" первая метка "label2 = 'Это вторая \' метка ']
и это должен быть массив результатов:
массив ( [id] => 8411 [label] => Это первая метка [label2] => Это второй ярлык )
У меня есть это регулярное выражение:
$ atts_arr = preg_split ('~ \ s + (? = (?: [^ \' "] * [\ '"] [^ \' "] * [\ '"]) * [^ \' "] * $) ~ ', trim ($ shortcode,' [] '));
К сожалению, это работает, только если нет кавычек \'
или же \"
,
Спасибо заранее!
С помощью 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']);
Других решений пока нет …