Aiutare con un'espressione regolare che estrae spazi bianchi
Domanda
sto modificando una funzione centrale della biblioteca Kohana, il testo :: auto_p () funzione.
La funzione si descrive come "nl2br () con gli steroidi". In sostanza, fornisce <br />
interruzioni di riga singola, ma doppie interruzioni di riga sono circondati con i tag <p>
.
La limitazione ho trovato con esso è che sarà, ma <br />
s in un elemento <pre>
. Questo creerà nuove linee doppie, che non è quello che voglio. Ho fatto una modifica per raccogliere elementi pre con regex, e un callback che togliere i <br />
che funziona bene.
Tuttavia, il problema principale è che non ho esempi di codice nel mio testo che viene auto_p()
'd, e ho bisogno di preservare il rientro (per migliorare la leggibilità). Purtroppo per me, le strisce delle funzioni iniziali e finali spazio bianco su linee.
Qui è l'espressione regolare che mette a nudo spazio iniziale
$str = preg_replace('~^[ \t]+~m', '', $str);
Non sono il migliore guru regex, ma sono abbastanza sicuro che dice "Get principali spazi e tabulazioni in cui v'è almeno uno e sostituirli con una stringa vuota".
Ho provato a rimuovere questa linea, ma poi aggiungerò <br />
dove io sicuramente non li voglio - in un caso, mi è stato sempre output come questo
<ul><br />
<li>something</li>
</ul>
Come potrei modificare questo regex o un codice di non spogliare leader spazio all'interno di un elemento <pre>
?
la funzione di supporto originale dal Kohana è disponibile qui . (Scorrere fino alla quasi in basso).
Lo so mi metterò un paio di 'utilizzare un parser HTML' di tipo risposte - e mentre si può essere corretto - il codice esistente usa semplicemente regex, e preferirei una soluzione più semplice (dove non ho includere un biblioteca, ecc).
Grazie per il vostro tempo.
Soluzione
Ecco come lo farei:
$str = preg_replace(
'~^[ \t]++(?=(?:[^<]++|<(?!/?+pre\b))*+(?:\z|<pre\b))~im',
'', $str);
Dopo aver fatto corrispondere alcuni spazi bianchi line-leader, il lookahead scansioni in anticipo per <pre>
o </pre>
tag. La carne del lookahead è questo bit:
(?:[^<]++|<(?!/?+pre\b))*+
E 'corrisponde a zero o più di tutto ciò che non è una parentesi angolare sinistra, o una parentesi angolare sinistra se non è l'inizio di un tag o <pre>
</pre>
. Quella parte si fermerà solo corrispondenza a quando incontra un tag <pre>
(partenza), un tag </pre>
(fine), o la fine dell'input. Se si tratta di un tag di chiusura che si ferma, lo sai che sei all'interno di un elemento <PRE>
, in modo che non si vuole fare la sostituzione.
I quantificatori possessivi ('++'
, '*+'
e '?+'
) sono essenziali per prevenire backtracking catastrofica . (Non posso farne a meno: quella frase mi fa sempre pensare al risonanza cascata scenario da Half-life .)
Questa tecnica presuppone anche ragionevolmente ben formato HTML, vale a dire, tutti i tag <pre>...</pre>
correttamente bilanciata. Tag all'interno di SGML commenti volontà rovinare tutto, anche - a meno che non capita di essere equilibrati. Si può trattare con i commenti, anche, se non ti dispiace fare la regex il doppio del tempo e tre volte più brutto. :)
Altri suggerimenti
Il tuo problema è discusso un sacco Credo - controlla questo link
http://us3.php.net/manual/en /function.nl2br.php#91828
Questo così: