Padrão Regex para códigos curtos em PHP

Tenho um problema com um regex que escrevi para combinar códigos curtos em PHP.

Este é o padrão, onde $shortcode é o nome do shortcode:

 \[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])? 

Agora, esta regex se comporta muito bem com esses formatos:

  • [shortcode]
  • [shortcode=value]
  • [shortcode key=value]
  • [shortcode=value]Text[/shortcode]
  • [shortcode key1=value1 key2=value2]Text[shortcode]

Mas parece ter problemas com o formato mais comum,

  • [shortcode]Text[/shortcode]

que retorna como corresponde ao seguinte:

 Array ( [0] => [shortcode]Text[/shortcode] [1] => ]Text[/shortcode ) 

Como você pode ver, a segunda partida (que deve ser o texto, como o primeiro é opcional) inclui o final da etiqueta de abertura e toda a etiqueta de fechamento, mas o último suporte.

EDIT: descobriu que o jogo retornou é a primeira captura , e não a segunda. Veja o regex em Regexr.

Você pode ajudar com isso, por favor? Estou realmente esmagando minha cabeça nessa.

Em sua regex:

 \[$shortcode(.+?)?\](?:(.+?)?\[\/$shortcode\])? 

O primeiro grupo de captura (.+?) Corresponde a pelo menos 1 caractere.

Todo o grupo é opcional, mas neste caso acontece combinar tudo até o último ] .

O seguinte regex funciona:

 \[$shortcode(.*?)?\](?:(.+?)?\[\/$shortcode\])? 

O * quantificador significa 0 ou mais, enquanto + significa um ou mais.

Concedido isto é de C #, mas

 @"\[([\w-_]+)([^\]]*)?\](?:(.+?)?\[\/\1\])?" 

deve corresponder a qualquer (?) possivelmente fechamento de fechamento.

Ou você poderia roubar do wordpress: https://core.trac.wordpress.org/browser/tags/4.0/src/wp-includes/shortcodes.php#L309

 $pattern = '/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/'; $text = preg_replace("/[\x{00a0}\x{200b}]+/u", " ", $text); if ( preg_match_all($pattern, $text, $match, PREG_SET_ORDER) )...