Repetición de expersión regular dentro de un patrón
Frecuentes
Visto 942 veces
1
Tengo el siguiente texto y me gustaría preg_match_all
que hay dentro del {
y }
's si contiene sólo a-zA-Z0-9
y :
some text,{SOMETHING21} {SOMETHI32NG:MORE}some msdf{TEXT:GET:2}sdfssdf sdf sdf
Estoy tratando de igualar {SOMETHING21}
{SOMETHI32NG:MORE}
{TEXT:GET:2}
puede haber varios :
está dentro de la etiqueta.
Lo que tengo actualmente es:
preg_match_all('/\{([a-zA-Z0-9\-]+)(\:([a-zA-Z0-9\-]+))*\}/', $from, $matches, PREG_SET_ORDER);
Funciona como se esperaba para {SOMETHING21}
y {SOMETHI32NG:MORE}
pero para los {TEXT:GET:2}
solo coincide TEXT
y 2
Por lo tanto, solo coincide con la primera y la última palabra dentro de la etiqueta, y deja las del medio fuera de la $matches
formación. ¿Es esto posible o debería simplemente emparejarlos y luego explotar en :
?
editar
Bueno, la pregunta no es si puedo obtener las etiquetas, la pregunta es si puedo agruparlas sin tener que explotar los resultados nuevamente. Aunque mi expresión regular actual encuentra todos los resultados, el subpatrón no regresa con todas las coincidencias en $matches
.
Espero que lo siguiente lo aclare un poco más:
\{ // the match has to start with {
([a-zA-Z0-9\-]+) // after the { the match needs to have alphanum consisting out of 1 or more characters
(
\: // if we have : it should be followed by alphanum consisting out of 1 or more characters
([a-zA-Z0-9\-]+) // <---- !! this is what it is about !! even though this subexpression is between brackets it is not put into $matches if more then one of these is found
)* // there could be none or more of the previous subexpression
\} // the match has to end with }
3 Respuestas
2
No puede obtener todos los valores coincidentes de un grupo de captura, solo obtiene el último.
Así que tienes que hacer coincidir el patrón:
preg_match_all('/{([a-z\d-]+(?::[a-z\d-]+)*)}/i', $from, $matches);
y luego dividir cada elemento en $matches[1]
on :
.
respondido 09 mar '12, 16:03
1
Utilicé agrupaciones sin captura para eliminar los grupos internos, y solo capturé la lista externa completa separada por dos puntos.
$from = "some text,{SOMETHING21} {SOMETHI32NG:MORE}some msdf{TEXT:GET:2}sdfssdf sdf sdf";
preg_match_all('/\{((?:[a-zA-Z0-9\-]+)(?:\:(?:[a-zA-Z0-9\-]+))*)\}/', $from, $matches, PREG_SET_ORDER);
print_r($matches);
Resultado:
Array
(
[0] => Array
(
[0] => {SOMETHING21}
[1] => SOMETHING21
)
[1] => Array
(
[0] => {SOMETHI32NG:MORE}
[1] => SOMETHI32NG:MORE
)
[2] => Array
(
[0] => {TEXT:GET:2}
[1] => TEXT:GET:2
)
)
respondido 09 mar '12, 15:03
0
Tal vez no entendí el requisito, pero...
preg_match_all('/{[A-Za-z0-9:-]+}/', $from, $matches, PREG_PATTERN_ORDER);
resulta en:
Array
(
[0] => Array
(
[0] => {SOMETHING21}
[1] => {SOMETHI32NG:MORE}
[2] => {TEXT:GET:2}
)
)
respondido 09 mar '12, 16:03
No es la respuesta que estás buscando? Examinar otras preguntas etiquetadas php regex preg-match or haz tu propia pregunta.
Necesidad de escapar de la
{
corchete rizado. De lo contrario +1 - ridgerunner@ridgerunner, no necesitas escapar
{
en este caso. - QimpuestoTenía la esperanza de poder hacer esto sin tener que explotar mi
$matches[1]
. De todos modos, gracias por aclararlo. - Jeffreydev@jeffreydev, .NET regex es el único sabor con el que podrías hacer eso. Pero si tiene un número limitado conocido de
:
puede usar grupos de captura opcionales si lo desea. - Qimpuesto