IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage PHP Discussion :

utilisation regex pour pagination articles


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Par défaut utilisation regex pour pagination articles
    salut tt le monde,

    j'ai un problème d'url rewriting sur serveur lighttpd, et comme je débute en regex, j'ai toujours quelques souçis pour m'en dépatouiller..

    voici mon problème :
    je voudrais écrire un regex qui me permette d'afficher plusieurs types d'url de pages , par ex :
    http://www.mondomaine.com/actu/2010/03/17/titre_article
    et
    http://www.mondomaine.com/actu/2010/...itre_article/1
    http://www.mondomaine.com/actu/2010/...itre_article/2
    et
    http://www.mondomaine.com/actu/insolite

    dans mon lighttpd.conf, j'ai écrit la regex suivante qui me permet de matcher les 3 premieres url, mais pas la 4e :
    "^/(.*\/\d{4}\/\d{2}\/\d{2})/([0-9a-zA-Z-_]+)/?([0-9{0,1})$" => "/index.php?module=$1&opts=$2&pagination=$3"

    alors que la regex suivante permet de matcher la 4e mais pas la pagination d'articles :
    "^/(.*)/(.*)?$" => "/index.php?module=$1&opts=$2"

    quelqu'un pourrait-il m'aider à matcher toutes les url ?
    merci d'avance à tous !!

  2. #2
    Membre Expert
    Profil pro
    Inscrit en
    Janvier 2007
    Messages
    1 418
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2007
    Messages : 1 418
    Par défaut
    Bonjour,


    Ta première RE ne peut pas matcher avec les 3 premières url:

    - en PHP, le second caractère d'une RE est un délimiteur, qui doit se retrouver à la fin de la RE avant les indications d'options.
    Le caractère ^ est le second et le seul dans la chaîne que tu donnes.

    - il manque un crochet dans ([0-9{0,1})$ à la fin


    Ta seconde RE est aussi non conforme relativement aux délimiteurs.




    Par ailleurs il y a des imperfections dans tes RE:

    Premièrement
    Que fait le moteur de regex quand il exécute la portion /.*/\d{4} de la première RE ?
    Nota: pour écrire cette portion, j'ai simplifié en:
    - ne mettant pas la parenthèse gauche qui ouvre simplement un groupe capturant
    - ne mettant pas l'antislash devant / car je ne saisis pas à quoi il sert.
    Il n'y a que devant un métacaractère ( par exemple le point . ou ? ou +, etc) ou devant un caractère avec lequel il produit une séquence (de 2 caractères) ayant une signification particulière dans une chaîne (par exemple, 't' précédé de '\' donne un caractère de tabulation, 'n' précédé de '\' donne un retour à la ligne,etc) qu'un antislash a une influence dans une RE.
    En dehors de ces cas, mettre un antislash devant un caractère quelconque dans une RE ne produit rien, l'antislash est simplement ignoré par le moteur de regex.

    Voici donc ce que fait le moteur de regex:

    1) Il cherche un caractère '/'
    Le premier qu'il détecte est celui juste après 'http:'

    2) La succession .*/ lui indique alors qu'il doit avancer tant qu'il ne rencontre pas le caractère '/'

    Comme je pense que tu vas spécifier U comme option, je considère les quantificateurs "ungreedy".

    Le moteur de regex devra s'arrêter dès le nouvel autre '/' qui se présentera, et le moteur n'a pas à aller bien loin pour trouver ce second '/', c'est le deuxième de 'http://' (l'étoile * autorisant 0 caractères entre le premier '/' et le second '/').

    .*/ matchera donc le second '/' de 'http://'

    3) À ce moment là, le moteur de regex doit continuer en trouvant un motif \d{4} . Mais il ne trouve pas ce motif après le deuxième '/' matché.
    Le moteur de regex doit alors laisser tomber le '/' qu'il a trouvé comme deuxième '/' et recommencer de le chercher.

    Le moteur de regex va aller cette fois jusqu'à la fin de
    'http://www.mondomaine.com/' .

    4) Rebelote, il ne trouve pas de motif \d{4} à la suite.
    Le moteur est à nouveau obligé de recommencer, c'est à dire en cherchant le '/' encore plus en aval dans la chaîne.

    5) Enfin, cette nouvelle recherche lui permet de matcher correctement,
    non seulement .*/ avec 'http://www.mondomaine.com/actu/' mais aussi la suite \d{4} avec '2010'


    Cela fait des essais-erreurs inutiles qu'il y a moyen d'éviter au moteur de regex: il faut doubler les slashes en tête de RE pour lui éviter de s'arrêter sur le second slash après 'http:', et tant qu'à faire si tu es sûr qu'il y a toujours au moins une plage 'www.mondomaine.com/' avant 4 chiffres, il faut écrire '//.+?/.*?/\d{4}'

    Tout ça pour dire que quand on dispose d'information sur la structure de la chaîne explorée, il faut en faire profiter le moteur de regex pour lui éviter du travail inutile. De plus ça accroît la précision de la RE.



    Deux,
    [0-9a-zA-Z_] est \w
    donc [0-9a-zA-Z-_] est [-\w]


    Trois,
    /?([0-9{0,1}) est balourd
    /?[0-9]* ou /?\d*
    sera mieux






    J'écrirais donc ta RE pour les 3 premières url plutôt ainsi, en PHP:
    "#/(/.+?/.*?/\d{4}/\d{2}/\d{2})/([-\w]+)/?(\d*)#U"




    Mais dans la 4ième url, il n'y a pas de chiffres et donc il ne peut pas y avoir de suite matchant avec
    ([-\w]+)/?(\d*)
    Je mets donc une assertion conditionnelle:
    (?(2)YES-pattern|NO-pattern) signifiant: si le groupe 2 capture quelque chose alors il doit y avoir ici un pattern YES , sinon il doit y avoir un pattern NO. L'indication du NO-pattern est facultative.


    Au final, j'aboutis à :

    "#/(/.+?/.*?/(\d{4}/\d{2}/\d{2})?)(?(2)/([-\w]+)/?(\d*)|(.*?))$#U"


    En Python, ça donne ceci ( je ne connais bien que Python):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    RE = "/(/.+?/.*?/(\d{4}/\d{2}/\d{2})?)(?(2)/([-\w]+)/?(\d*)|(.*?))$"
    pat = re.compile(RE)
    for dh in ('http://www.mondomTaine.com/actu/2010/03/17/titre_article',
               'http://www.mondoTmaine.com/actu/2010/03/17/titre_article/2',
               'http://www.mondomaine.com/actu/insolite'):
        print '\nurl =',dh
        m = pat.search(dh)
        for i in xrange(6):
            print 'groupe',i,m.group(i)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    url = <a href="http://www.mondomTaine.com/actu/2010/03/17/titre_article" target="_blank">http://www.mondomTaine.com/actu/2010.../titre_article</a>
    groupe 0 //www.mondomTaine.com/actu/2010/03/17/titre_article
    groupe 1 /www.mondomTaine.com/actu/2010/03/17
    groupe 2 2010/03/17
    groupe 3 titre_article
    groupe 4 
    groupe 5 None
     
    url = <a href="http://www.mondoTmaine.com/actu/2010/03/17/titre_article/2" target="_blank">http://www.mondoTmaine.com/actu/2010...itre_article/2</a>
    groupe 0 //www.mondoTmaine.com/actu/2010/03/17/titre_article/2
    groupe 1 /www.mondoTmaine.com/actu/2010/03/17
    groupe 2 2010/03/17
    groupe 3 titre_article
    groupe 4 2
    groupe 5 None
     
    url = <a href="http://www.mondomaine.com/actu/insolite" target="_blank">http://www.mondomaine.com/actu/insolite</a>
    groupe 0 //www.mondomaine.com/actu/insolite
    groupe 1 /www.mondomaine.com/actu/
    groupe 2 None
    groupe 3 None
    groupe 4 None
    groupe 5 insolite

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    5
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 5
    Par défaut
    en effet, j'ai kk lacunes en regex..merci pour le cours

    je viens d'essayer, et ça ne marche pas, sur lighttpd apparemment l'ecriture des regex differe de celle d'apache, on ne prend pas en compte les delimiteurs, je ne sais pas comment prendre e ncompte l'option U..
    comment prendre e ncompte U sans delimiteurs ?

    merci en tt cas, appris pas mal de choses ce soir

Discussions similaires

  1. Utilisation de Regex pour regrouper des emails
    Par NicoNGRI dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 18/02/2008, 16h51
  2. Utiliser Regex pour remplacement
    Par soveste dans le forum Collection et Stream
    Réponses: 13
    Dernier message: 19/03/2007, 09h48
  3. [Notepad++] utiliser regex pour remplacer des caractères
    Par ilood dans le forum Autres Logiciels
    Réponses: 2
    Dernier message: 04/02/2007, 04h06
  4. [MySQL] Utilisation LIMIT pour une pagination
    Par tilou dans le forum PHP & Base de données
    Réponses: 3
    Dernier message: 16/05/2006, 08h29

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo