Problemas com tubulação em expressão regular PHP
Pergunta
Eu tenho escrito um plugin para Joomla que processa automaticamente HTML comenta por exemplo. {Dropcap} B {/ dropcap} e cria um estilo capitular.
Eu precisava de uma maneira de passar parâmetros para o plugin assim, portanto, decidiu que a melhor forma seria:. {Dropcap} B | FF00FF | 00FF00 {/ dropcap}
Eu criei uma função:
if (preg_match_all('/{dropcap}(.+?){\/dropcap}/', $row->text, $matches, PREG_PATTERN_ORDER) > 0)
{
foreach ($matches[0] as $match)
{
$SimpleDropCapPlugin->html = "";
$_temp = preg_replace("/{.+?}/", "", $match);
$_params = explode('|', $_temp);
$SimpleDropCapPlugin->text_dropcap = $_params[0];
if ($_params[1])
$SimpleDropCapPlugin->colour_border = '#' . $_params[1];
if ($_params[2])
$SimpleDropCapPlugin->colour_background = '#' . $_params[2];
if ($_params[3])
$SimpleDropCapPlugin->colour_text = '#' . $_params[3];
if ($_params[4])
$SimpleDropCapPlugin->font_size = $_params[4];
if ($_params[5])
$SimpleDropCapPlugin->font_family = $_params[5];
$SimpleDropCapPlugin->html .= "<span style=\"border: 1px solid " . $SimpleDropCapPlugin->colour_border . "; background: " . $SimpleDropCapPlugin->colour_background . " none repeat scroll 0% 0%; margin-right: 6px; margin-top: 5px; float: left; color: " . $SimpleDropCapPlugin->colour_text . "; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial; font-size: " . $SimpleDropCapPlugin->font_size . "px; line-height: 60px; padding-top: 2px; padding-right: 5px; font-family: " . $SimpleDropCapPlugin->font_family . ";\">";
$SimpleDropCapPlugin->html .= strtoupper($SimpleDropCapPlugin->text_dropcap);
$SimpleDropCapPlugin->html .= "</span>";
$row->text = preg_replace( "#{dropcap}".$_temp."{/dropcap}#s", $SimpleDropCapPlugin->html , $row->text );
}
}
Se eu usar o '|' caráter o script funciona, mas cria um dropcap separado cada vez que o carácter de pipe é usado, enquanto que se eu usar um diferente seperator por exemplo. ':'. O script funciona bem
Eu definitivamente quero usar o caractere pipe, uma vez que não é normalmente usado em HTML assim, portanto, posso estender o uso do plugin, existe alguma maneira de parar este comportamento estranho?
Solução
O problema é que '|' é um caractere especial em expressões regulares. Você precisa usar preg_quote escapar-lo aqui:
$row->text = preg_replace( "#{dropcap}".preg_quote($_temp,'#')."{/dropcap}#s", $SimpleDropCapPlugin->html , $row->text );
Na verdade, não há nenhuma razão para sequer incluem US $ _temp em que regex, você pode simplesmente fazer isso:
$row->text = preg_replace( "#{dropcap}.+?{/dropcap}#s", $SimpleDropCapPlugin->html , $row->text );
Correção :. Mediante um exame mais detalhado, você precisa usar $ _temp, pelo menos na sua implementação, porque você está substituindo sobre toda uma fileira de texto que pode ter vários droptags nele