Posterior a indagar en varios repositorios y sitios de internet al terminar encontramos la resolución que te enseñaremos pronto.
PHP no tiene un método regex que busque un string de derecha a izquierda (como en .net). Hay varias recetas posibles para resolver eso (esta lista no es exhaustiva, pero puede proporcionar ideas para su propia solución):
- utilizando
preg_match_all
conPREG_SET_ORDER
bandera yend($matches)
te dará el último conjunto de partidos - invirtiendo el string con
strrev
y construyendo un patrón “invertido” para usar con preg_match - utilizando
preg_match
y construyendo un patrón anclado al final de la string que asegura que no haya más ocurrencias de la máscara buscada hasta el final de la string - usando un cuantificador codicioso antes del objetivo y
K
para iniciar el resultado del partido en la posición que desee. Una vez finalizada la string se alcanza, el motor de expresiones regulares retrocederá hasta que encuentre una coincidencia.
Ejemplos con el string $str = 'xxABC1xxxABC2xx'
para el patrón /x[A-Z]+d/
camino 1: encuentra todas las coincidencias y muestra la última.
if ( preg_match_all('/x[A-Z]+d/', $str, $matches, PREG_SET_ORDER) )
print_r(end($matches)[0]);
manifestación
camino 2: encuentra la primera coincidencia del inverso string con un patrón invertido y muestra el resultado invertido.
if ( preg_match('/d[A-Z]+x/', strrev($str), $match) )
print_r(strrev($match[0]));
manifestación
Tenga en cuenta que no siempre es tan fácil invertir un patrón.
camino 3: Salta de x a x y comprueba con la anticipación negativa si no hay otra x[A-Z]+d
partidos desde el final de la string.
if ( preg_match('/x[A-Z]+d(?!.*x[A-Z]+d)/', $str, $match) )
print_r($match[0]);
manifestación
variantes:
Con un cuantificador perezoso
if ( preg_match('/x[A-Z]+d(?!.*?x[A-Z]+d)/', $str, $match) )
print_r($match[0]);
o con un “cuantificador templado”
if ( preg_match('/x[A-Z]+d(?=(?:(?!x[A-Z]+d).)*$)/', $str, $match) )
print_r($match[0]);
Puede ser interesante elegir entre estas variantes cuando se sabe de antemano dónde tiene más probabilidades de ocurrir una coincidencia.
camino 4: va al final de la string y retrocede hasta que encuentra un x[A-Z]+d
coincidir. El K
elimina el inicio de la string del resultado del partido.
if ( preg_match('/^.*Kx[A-Z]+d/', $str, $match) )
print_r($match[0]);
forma 4 (una variante más manual): para limitar los pasos de retroceso, puede avanzar con avidez desde el comienzo de la string, grupo atómico por grupo atómico, y retroceder de la misma manera por grupos atómicos, en lugar de por caracteres.
if ( preg_match('/^[^x]*+(?>x[^x]*)*Kx[A-Z]+d/', $str, $match) )
print_r($match[0]);
“Codicioso” es el key palabra aquí. * es por defecto codicioso *? limita la codicia al mínimo indispensable.
Entonces, la solución es usar la combinación, por ejemplo (buscando el último punto seguido de un espacio en blanco):
/^.*.s(.*?)$/s
- ^ es el comienzo del texto
- .* come todo lo que puede, incluidos los patrones coincidentes
- .s es el punto seguido de un espacio en blanco (lo que estoy buscando)
- (.*?) come lo menos posible. Grupo de captura () para poder abordarlo como un grupo de coincidencia.
- $ fin del texto
- s: se asegura de que las líneas nuevas se ignoren (no se traten como $ y ^, . el punto coincide con la línea nueva)