Una ayudita con expresiones regulares

A ver, que a veces me toca a mí pedirles una ayudita a los lectores programadores.

Resulta que estoy trabajando con el código del blog para que las urls del mísmo no aparezcan duplicadas para Google, actualmente el buscador me voló del índice unos 3000 posts, como se imaginarán no me pone muy contento. Una de las posibles razones son los duplicados, no es algo intencional, sólo que desde que puse la posibilidad de que los posts se vean como: http://www.fabio.com.ar/5014 esto generó un problema

La url original era más bien fea: http://www.fabio.com.ar/verpost.php?id_noticia=5014 y por eso la idea fue acortarla a algo más sencillo.

El tema es que Google ve dos ahora, http://www.fabio.com.ar/verpost.php?id_noticia=5014 y http://www.fabio.com.ar/5014 para una misma nota, considera que estoy haciendo algo sucio duplicando contenidos aun cuando ambos son exactamente el mismo.

Para ello ahora hago un redirect en php y le envío un código 301, éste implica que es contenido "movido" y no duplicado. OK, hasta ahí bárbaro y si hacen click en una url larga y vieja los llevará a la corta simplificada.

Pero aquí tengo un problema, herencia del código viejo de mi blog, esta es la regla que ajusta la url:

RewriteRule ^([0-9_]+)$ verpost.php?id_noticia=$1&vieja=1 [L]

Hasta ahí todo perfecto, Apache se encarga de pasarle el parámetro si es que viene un numerito (el id del post) y se lo pasa a la vieja estructura.

El problema es cuando, por ejemplo, para emitir un mensaje de error (onda, escribiste una palabra spammera o te equivocaste el código de seguridad) le pasaba un parámetro, la url quedaría así:

http://www.fabio.com.ar/5014&mensaje=4

El problema con esto es que 5014&mensaje=4 no significa nada para esa expresión regular y directamente me lo desecha como error 404, un despropósito.

Por esto necesito cambiar:

RewriteRule ^([0-9_]+)$ verpost.php?id_noticia=$1&vieja=1 [L]

de manera tal que contemple no sólo el número de ID del post si no los parámetros extra como "mensaje" y lo pase a la vieja url, de esta manera yo sería un blogger muy feliz y, tal vez algún día, Google considere este blog digno nuevamente en su totalidad y no sólamente para 1800 posts :P

¿Mi problema? nunca entendí bien las expresiones regulares, así es, soy bastante burro con las malditas y no sabría como hacer para que me genere el parámetro $2 para mensaje, no es difícil, lo se, pero zoy ezpezial :P ¿me ayudan?

Otros posts que podrían llegar a gustarte...

Comentarios

  • Agregando QSA dentro del ? De esta manera le pasás todos los argumentos luego del & a la nueva url.

    • Responder
    • Citar
    • Comentado:
  • Fabio,

    Yo probaría algo como...

    RewriteRule (^(+)$)(.*) verpost.php?id_noticia=$1&vieja=1$2

    Saludos
    Salvador
    Montevideo, Uruguay

    • Responder
    • Citar
    • Comentado:
  • Claro que con QSA no solucionarías el problema del repetido, sí o sí tiene que ser . Funcionará ?

    • Responder
    • Citar
    • Comentado:
  • marceloinxs dijo:

    Agregando QSA dentro del ? De esta manera le pasás todos los argumentos luego del & a la nueva url.


    in spanish please? :D

    • Responder
    • Citar
    • Comentado:
  • j0an    

    y meterle el tag de la URL canonical?

    http://www.mattcutts.com/blog/seo-advice-url-canonicalization/

    • Responder
    • Citar
    • Comentado:
  • j0an dijo:

    y meterle el tag de la URL canonical?

    http://www.mattcutts.com/blog/seo-advice-url-canonicalization/


    el canonical lo tenía ya puesto en el header pero por lo visto se lo está pasando por el traste :|


    Salvador Oria dijo:
    Fabio,

    Yo probaría algo como...

    RewriteRule (^(+)$)(.*) verpost.php?id_noticia=$1&vieja=1$2

    Saludos
    Salvador
    Montevideo, Uruguay


    no me funcó, más bien, no hizo nada distinto, y si saco el $ pasa tranquilo pero no envía el parámetro mensaje

    • Responder
    • Citar
    • Comentado:
  • Suponiendo que <strong>vieja=1</strong> es el parámetro que pasás junto con el código de artículo, podés probar con:

    RewriteRule ^(+.*)$ verpost.php?id_noticia=$1

    El ".*" representa ninguno o más elementos del tipo "." que sería cualquier tipo de caracter.

    • Responder
    • Citar
    • Comentado:
  • Leonardo Martinez dijo:

    Suponiendo que &lt;strong&gt;vieja=1&lt;/strong&gt; es el parámetro que pasás junto con el código de artículo, podés probar con:

    RewriteRule ^(+.*)$ verpost.php?id_noticia=$1

    El &quot;.*&quot; representa ninguno o más elementos del tipo &quot;.&quot; que sería cualquier tipo de caracter.


    TOUCHÉ!

    ahí funcionó, estaba cerquita, era el orden de los factores, como siempre en expresiones regulares Guiño


    MIL GRACIAS!

    ahora al menos podemos decir que no sólo le puse las urls canónicas si no que también tiene el maldito 301 y la mar en coche


    probablemente Google tarde 1500 años en devolverme los posts al índice pero al menos que no tire errores en el webmastertools!

    • Responder
    • Citar
    • Comentado:
  • Iba a decir

    RewriteRule ((+))(.*) verpost.php?id_noticia=$1&amp;vieja=1$2

    pero lo que propone Leonardo creo que queda más lindo Guiño

    Sds!

    • Responder
    • Citar
    • Comentado:
  • pd: De paso recomiendo regexpal.com para boludear con expresiones regulares...

    • Responder
    • Citar
    • Comentado:
  • Planteemos bien el asunto:

    RewriteRule ^(+)$ verpost.php?id_noticia=$1&vieja=1
    Hace que:
    http://www.fabio.com.ar/5014
    Redirige a:
    http://www.fabio.com.ar/verpost.php?id_noticia=5014

    Como?
    ^ <- Del principio de la string
    + <- Cualquier numero del 0 al 9 más el _, repetido una o más veces
    $ <-- Seguido del final de la string

    Matchea y lo convierte en verpost.php?id_noticia=$1&vieja=1 , donde $1 es lo primero encerrado entre paréntesis.

    Si querés que acepte argumentos aparte de simplemente el número, agregá una expresión más para que también acepte argumentos. Pero te recomiendo que seas restrictivo con la regex, porque un (.*) matchea cualquier cosa, como "piñonfijosetomael71" como algo válido y podría representar un problema de seguridad.

    http://www.fabio.com.ar/5014&mensaje=4

    Podría expresarse como

    ^(+)((&+)+)$
    O sea, el número seguido de una cantidad indefinida de &

    Tonces, el RewriteRule sería:
    RewriteRule ^(+)((&+)+)$ verpost.php?id_noticia=$1&vieja=1$2

    Entonces, cuando encuentre:
    http://www.fabio.com.ar/5014&mensaje=4
    http://www.fabio.com.ar/5014&mensaje=4&pepito=4
    Lo traduce a:
    http://www.fabio.com.ar/verpost.php?id_noticia=5014&mensaje=4&pepito=4

    Por lo que leí ese es el comportamiento que buscabas.
    Un saludo.

    • Responder
    • Citar
    • Comentado:
  • Corrijo lo anterior.

    Cuando ve:
    http://www.fabio.com.ar/5014&mensaje=4
    http://www.fabio.com.ar/5014&mensaje=4&pepito=4
    Lo traduce a:
    http://www.fabio.com.ar/verpost.php?id_noticia=5014&mensaje=4
    http://www.fabio.com.ar/verpost.php?id_noticia=5014&mensaje=4&pepito=4

    Pero cuando ve:
    http://www.fabio.com.ar/5014&mensaje=4&&hola
    Se rompe y manda 403.

    • Responder
    • Citar
    • Comentado:
  • tucho    

    avergaston... se me ocurre esto... (y es bien feo) :D

    RewriteRule ^(+(&(mensaje|vieja)=(+)){0,1}$ verpost.php?id_noticia=$1

    • Responder
    • Citar
    • Comentado:
    • Revisado: 16/05/2012 - 18:55:45
  • frostwarrior dijo:

    Corrijo lo anterior.

    Cuando ve:
    http://www.fabio.com.ar/5014&amp;mensaje=4
    http://www.fabio.com.ar/5014&amp;mensaje=4&amp;pepito=4
    Lo traduce a:
    http://www.fabio.com.ar/verpost.php?id_noticia=5014&amp;mensaje=4
    http://www.fabio.com.ar/verpost.php?id_noticia=5014&amp;mensaje=4&amp;pepito=4

    Pero cuando ve:
    http://www.fabio.com.ar/5014&amp;mensaje=4&amp;&amp;hola
    Se rompe y manda 403.


    ja y como sería para que no de 403?

    • Responder
    • Citar
    • Comentado:
  • Sería
    http://www.fabio.com.ar/
    El se repite indefinidamente pero está obligado a seguir ese patrón. Así que si ponés:
    http://www.fabio.com.ar/5014&mensaje=4$
    http://www.fabio.com.ar/5014&mensaje=4&&hola <-- Doble &
    http://www.fabio.com.ar/5014&mensaje=4&nuevo-argumento=3
    En cualquiera de los casos rompe y tira 403.

    ((&+)+)
    Este regex extra se escribiría en letra:
    & <- Un ampersand seguido de cualquier alfanumérico junto con el ´_´ y el ´=´
    como el bloque entre sigue de un +, ese bloque se repite indefinidamente.
    Por lo que matchea "&holacomo_teva=4"
    Ahora, todo el ampersand y bloque repetido lo encierro entre paréntesis y le pongo un + para que repita ese bloque también. For dentro de un for
    Por lo que matchea "&holacomo_teva=4&holacomoteva=4&holacomoteva=4..."

    Mientras que:
    ^(+.*)$
    Acepta
    "http://www.fabio.com.ar/5012holacomoteva_$!#:P"
    Porque es una sucesión de números seguido de CUALQUIER COSA.

    • Responder
    • Citar
    • Comentado:
  • Gus    

    Como dijeron en el primer comentario, con QSA que es una directiva de Apache al igual que R, L, etc. te evitás tener que hacer todas esas cosas con RegEx para detectar el querystring. QSA simplemente quita los parámetros del querystring para aplicar la expresión regular y los vuelve a anexar en url final (QSA = Query String Append)

    Para utilizarla basta con agregarla al final de las reglas:

    RewriteRule ^(+)$ verpost.php?id_noticia=$1&vieja=1

    Y chau picho, creo que es la solución más elegante

    • Responder
    • Citar
    • Comentado:
  • javiercyn    

    Fabio, he programado en C, C++, Java, Javascript, PL/SQL, Perl, etc. y laburado en analisis de sistemas. Humildemente creo que las expresiones regulares, si bien sirven para diseñar patrones y alguna otra cosa, son lo que en lenguaje ingenieril solemos llamar una m-i-e-r-d-a :D
    Saludos y felicitaciones por tu blog, lo leo por RSS.

    • Responder
    • Citar
    • Comentado:
  • NP    

    Bueno, paso a dejar mi comentario (que nada aporta) de apoyo a Fabio, ya que soy otro programador que nunca se llevo bien con las expresiones regulares.

    Salutes!

    • Responder
    • Citar
    • Comentado:
  • disparo    

    Fabio. A ver si en agradecimiento a la gente, permites unas pocas ruletas rusas, (unas 10 XD), desde RSS. Que se te subió el guapo, y ya siempre haces que entremos en la web.

    • Responder
    • Citar
    • Comentado:
  • Jonyx4    

    :D

    • Responder
    • Citar
    • Comentado:
  • disparo dijo:

    Fabio. A ver si en agradecimiento a la gente, permites unas pocas ruletas rusas, (unas 10 XD), desde RSS. Que se te subió el guapo, y ya siempre haces que entremos en la web.


    el pibe pide ruletas a mansalva y encima ni se quiere mover del RSS pero no provee ni una sola expresión regular? aaaaaah nooooo :D

    gracias a los que ayudaron, la ruleta se queda como está, sin cambios en el frente :D

    • Responder
    • Citar
    • Comentado:
  • Gus dijo:

    Como dijeron en el primer comentario, con QSA que es una directiva de Apache al igual que R, L, etc. te evitás tener que hacer todas esas cosas con RegEx para detectar el querystring. QSA simplemente quita los parámetros del querystring para aplicar la expresión regular y los vuelve a anexar en url final (QSA = Query String Append)

    Para utilizarla basta con agregarla al final de las reglas:

    RewriteRule ^(+)$ verpost.php?id_noticia=$1&amp;vieja=1

    Y chau picho, creo que es la solución más elegante


    probé así con la coma y el QSA y se me clava en un error 500, onda queda clavado

    estoy usando

    RewriteRule ^(+.*)$ verpost.php?id_noticia=$1&vieja=1

    y está funcionando ok, espero que siga así!

    • Responder
    • Citar
    • Comentado:
  • Gus    

    Lo que funciona no se toca :D Pero por si le sirve a alguien más, el problema es el espacio después de la coma

    debería funcionar

    • Responder
    • Citar
    • Comentado:
  • enanox    

    marceloinxs dijo:

    Agregando QSA dentro del ? De esta manera le pasás todos los argumentos luego del &amp; a la nueva url.


    esta es la solucion que yo use en otro momento en un sitio, asi no te tenes que andar preocupando de procesar en el orden correcto todos los parametros (ej.: una paginacion, filtros de busqueda, etc)

    • Responder
    • Citar
    • Comentado:
  • Solo queria decir que las expresiones regulares son irrregulares en su comportamiento.
    Te odio expresiones regulares y patrones! :D

    • Responder
    • Citar
    • Comentado:
  • Las Vegas    

    El otro día me cruce con un texto escrito en español del siglo 16 y tampoco entendí una chota. Felicitaciones por haber arreglado el coso ese! Guiño

    • Responder
    • Citar
    • Comentado:
  • pablodc    

    para expresiones regulares...recomiendo...

    http://gskinner.com/RegExr/

    Tiene librería de cosas ya resueltas y te permite crear tu propia librería en el sitio...

    • Responder
    • Citar
    • Comentado:
  • Jorge    

    Te recomiendo la pagina de stackoverflow, es le mejor lugar para preguntar estas cosas

    • Responder
    • Citar
    • Comentado:
  • RewriteRule ^(+.*)$ verpost.php?id_noticia=$1&vieja=1&%{QUERY_STRING}

    Abrazo.

    • Responder
    • Citar
    • Comentado:

Deje su comentario:

Tranquilo, su email nunca será revelado.
La gente de bien tiene URL, no se olvide del http/https
Para evitar bots, si se tardó mucho en leer la nota seguramente no sirva y tenga que intentar dos veces

Negrita Cursiva Imagen Enlace


comentarios ofensivos o que no hagan al enriquecimiento del post serán borrados/editados por el administrador