Regex para análisis de texto en cursiva?
Pregunta
Supongamos que tengo el siguiente texto:
__This_is__ a __test__
Uso de dos subrayos para denotar cursiva. Entonces espero This_is
y test
estar en cursiva. La lógica dicta que cualquier texto entre dos subrayos dobles consecutivos debe estar en cursiva, incluido cualquier otro número de subrayos que puedan estar allí. Tengo:
__([^_]+)__
¿Cuál es el equivalente de "no dos subrayadores consecutivos" en el Grupo 1? Gracias.
Solución
Una opción sería coincidir con dos subrayos:
__
Luego, haga una mirada negativa hacia adelante para ver si no hay dos subrayadores antes de la posición actual:
__(?!__)
Si ese no es el caso, coincida con cualquier personaje:
__(?!__).
y repita la anterior una o más veces:
__((?!__).)+
Y finalmente coincide con otros dos subrayadores:
__((?!__).)+__
cuál es la solución final.
Una pequeña demostración:
<?php
$text = '__This_is__ a __test__';
preg_match_all('/__(?:(?!__).)+__/', $text, $matches);
print_r($matches);
?>
produce:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
)
como se puede ver en Ideona.
EDITAR
Tenga en cuenta que utilicé un grupo no capturador en mi demostración, de lo contrario, la salida se habría visto así:
Array
(
[0] => Array
(
[0] => __This_is__
[1] => __test__
)
[1] => Array
(
[0] => s
[1] => t
)
)
es decir, el último personaje emparejado por ((?!__).)
habría sido capturado en el Grupo 1.
Más sobre grupos, ver: http://www.regular-expressions.info/brackets.html
Otros consejos
$text = '__This_is__ a __test__';
preg_match_all('/(__([\w]+)__)/', $text, $matches);
print_r($matches);