Actualmente estoy separando las reglas css usando
preg_match_all( '/(?ims)([a-z0-9s,.:()#_\-@>*]+){([^}]*)}/', $content, $arr);
Está funcionando bien. Sin embargo, si tengo corchetes dobles como este
@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}
esta expresión regular no extraerá todas las reglas de animación debido a los corchetes dentro. Necesito ayuda para adaptar dicha regla para mirar los paréntesis externos e ignorar los internos.
Estos deberían ser los resultados:
1: @keyframes animationName1{0%{opacity: 0}100%{opacity:1}} 2: div{opacity:0} 3: @keyframes animationName2{0%{opacity: 0}100%{opacity:1}}Puedes usar
([^{}]+)({((?:[^{}]++|(\g<2>))*)})Vea la demostración de expresiones regulares . Detalles :
([^{}]+) - Grupo de captura 1: uno o más caracteres distintos de { y }({((?:[^{}]++|(\g<2>))*)}) - Grupo 2:{ - un { carácter((?:[^{}]++|(\g<2>))*) - Grupo 3: cero o más apariciones de uno o más caracteres que no sean { y } o patrón del Grupo 2 (recursado)} - un } carácterVea la demostración de PHP :
$text = "@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}"; $rx = '~([^{}]+)({(?:[^{}]++|(\g<2>))*})~'; if (preg_match_all($rx, $text, $m)) { print_r($m[0]); }Producción:
Array ( [0] => @keyframes animationName1{0%{opacity: 0}100%{opacity:1}} [1] => div{opacity:0} [2] => @keyframes animationName2{0%{opacity: 0}100%{opacity:1}} )Si el formato es siempre el mismo, también puede hacer coincidir desde 2 curly de apertura hasta 2 curly de cierre comenzando con una @ o combinar caracteres de palabra seguidos de una sola apertura hasta cerrar curly.
(?s)@\w+\h+\w+\s*{[^{]*{.*?}\s*}|\w+{[^{}]+}(?s) Modificador en línea, haga que el punto coincida con una nueva línea (si está en varias líneas)@\w+\h+\w+\s* Coincide con @ y 1+ caracteres de palabra, espacios y nuevamente caracteres de palabra{[^{]*{ Coincidencia { luego caracteres opcionales que no sean { y nuevamente {.*? Coincidir con la menor cantidad posible de caracteres}\s*} Coincide con }} con espacios en blanco opcionales en el medio| O\w+{[^{}]+} Coincide con caracteres de palabra y de {...}Demostración de expresiones regulares
$re = '/(?s)@\w+\h+\w+\s*{[^{]*{.*?}\s*}|\w+{[^{}]+}/'; $str = '@keyframes animationName1{0%{opacity: 0}100%{opacity:1}}div{opacity:0}@keyframes animationName2{0%{opacity: 0}100%{opacity:1}}'; preg_match_all($re, $str, $matches); print_r($matches[0]);Producción
Array ( [0] => @keyframes animationName1{0%{opacity: 0}100%{opacity:1}} [1] => div{opacity:0} [2] => @keyframes animationName2{0%{opacity: 0}100%{opacity:1}} )