Regex per il testo del corsivo di analisi?
Domanda
Supponiamo di avere il seguente testo:
__This_is__ a __test__
Utilizzando due sottoti per indicare il corsivo. Quindi mi aspetto This_is
e test
essere in corsivo. La logica impone che qualsiasi testo tra due doppi punteggi consecutivi dovrebbe essere in corsivo, incluso qualsiasi altro numero di sottoti che potrebbero essere lì. Ho avuto:
__([^_]+)__
Qual è l'equivalente di "non due sottocorsi consecutivi" nel gruppo 1? Grazie.
Soluzione
Un'opzione sarebbe quella di abbinare due sottoti:
__
Quindi guarda uno sguardo negativo per vedere se non ci sono due sottoti di sotto la posizione attuale:
__(?!__)
Se non è così, abbina qualsiasi personaggio:
__(?!__).
e ripetere le precedenti o più volte:
__((?!__).)+
e infine abbina altri due sottoti:
__((?!__).)+__
che è la soluzione finale.
Una piccola demo:
<?php
$text = '__This_is__ a __test__';
preg_match_all('/__(?:(?!__).)+__/', $text, $matches);
print_r($matches);
?>
produce:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
)
Come si può vedere su Ideone.
MODIFICARE
Nota che ho usato un gruppo non catturato nella mia demo, altrimenti l'output sarebbe sembrato così:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
[1] => Array
(
[0] => s
[1] => t
)
)
cioè l'ultimo personaggio abbinato da ((?!__).)
Sarebbe stato catturato nel gruppo 1.
Maggiori informazioni sui gruppi, vedi: http://www.regular-espressions.info/brackets.html
Altri suggerimenti
$text = '__This_is__ a __test__';
preg_match_all('/(__([\w]+)__)/', $text, $matches);
print_r($matches);