Ajuda com um regex que retira levando espaço em branco
Pergunta
Eu estou modificando uma função central da biblioteca Kohana, a texto :: auto_p () função.
A função descreve-se como "nl2br () em esteróides". Essencialmente, ele fornece <br />
quebras de linha simples, mas quebras de linha duplas são cercados com as tags <p>
.
A limitação eu encontrei com ele é que ele vai, mas <br />
s em um elemento <pre>
. Isto irá criar duplas novas linhas, o que não é o que eu quero. Fiz uma modificação para pegar elementos pré com um regex, e uma chamada de retorno que irá retirar o <br />
que funciona bem.
No entanto, o principal problema é que eu tenho exemplos de código em meu texto que fica auto_p()
'd, e eu preciso para preservar o recuo (para facilitar a leitura). Infelizmente para mim, as tiras de função esquerda e à direita espaço em branco em linhas.
Aqui está a regex que tiras espaço à esquerda
$str = preg_replace('~^[ \t]+~m', '', $str);
Eu não sou o melhor guru regex, mas eu tenho certeza que diz "Get espaços à esquerda e guias em que há pelo menos um e substituí-los por uma cadeia vazia."
Eu tentei remover esta linha, mas, em seguida, ele irá adicionar <br />
onde eu definitivamente não quero que eles - em um caso, eu estava ficando saída como esta ??p>
<ul><br />
<li>something</li>
</ul>
Como eu iria modificar este regex ou código para não tira levando espaço dentro de um elemento <pre>
?
A função auxiliar original do Kohana está disponível aqui . (Rolagem para a quase inferior).
Eu sei que vou obter alguns 'Use um analisador HTML' respostas do tipo - e enquanto você pode estar correto - o código existente simplesmente usa regex, e eu preferiria uma solução mais simples (onde eu não tenho que incluem um biblioteca etc).
Obrigado pelo seu tempo.
Solução
Aqui está como eu faria isso:
$str = preg_replace(
'~^[ \t]++(?=(?:[^<]++|<(?!/?+pre\b))*+(?:\z|<pre\b))~im',
'', $str);
Depois de combinar algum espaço levando-line, o lookahead verifica com antecedência para <pre>
ou </pre>
tags. A carne do lookahead é este bit:
(?:[^<]++|<(?!/?+pre\b))*+
Ele corresponde a zero ou mais de qualquer coisa que não é um colchete angular esquerdo, ou um sinal de menor, se não é o início de uma <pre>
ou </pre>
tag. Essa parte só vai parar de correspondência quando encontra uma tag <pre>
(de partida), um tag </pre>
(final), ou o fim da entrada. Se é uma tag final que pára-lo, você sabe que está dentro de um elemento <PRE>
, para que você não quer fazer a substituição.
Os quantificadores possessivo ('++'
, '*+'
e '?+'
) são essenciais para evitar retrocesso catastrófico . (Eu não posso ajudá-lo: essa frase sempre me faz pensar no cenário de ressonância cascata ??em> de Half-Life .)
Esta técnica também assume razoavelmente HTML bem formado, ou seja, todas as tags <pre>...</pre>
devidamente equilibrada. Etiquetas dentro de comentários SGML vai mexer-se, também - a menos que acontecer a ser equilibrado. Você pode lidar com os comentários, também, se você não se importa de fazer a regex duas vezes mais longo e três vezes mais feio. :)
Outras dicas
Seu problema é discutido um monte eu acho - confira este link
http://us3.php.net/manual/en /function.nl2br.php#91828
Este bem: