Forum Programmation.php Regexp et retour à la ligne

Posté par  (site web personnel) .
Étiquettes : aucune
0
9
avr.
2005
Bonjour,

Je suis ultra-débutant en expressions régulières et j'aimerais faire quelque chose qui me semblait simplissime au premier abord: remplacer une chaîne quelconque qui se trouve entre deux autres chaînes bien définies.

En gros:
chaîneDebut.*chaîneFin

Le problème c'est que dans la chaîne quelconque, il y a des retours à la ligne. Et du coup rien n'est remplacé car le point représente tout sauf un retour à la ligne.

Là je me suis dit: "oh c'est rien, juste un petit \n à coller !".
Ben non :-/

Je n'ai absolument aucune idée de comment représenter ce curieux retour à la ligne qui n'est pas pris en compte par \n dans mon expression régulière.

D'après Google, il y a pas mal de monde qui a déjà rencontré ce problème. Mais je n'y ai trouvé aucune solution. Au moins je me sens moins seul :-)

Pour info la chaîne en question vient d'un simple fichier texte récupéré avec file().

Merci pour votre aide.
  • # .

    Posté par  (site web personnel) . Évalué à 4.

    Ceci devrait fonctionner :
    /^chaîneDébut((.+\n?)+)chaîneFin$/


    Explications :
    -> .+\n? = A = au moins un caractère quelconque suivi de zéro ou 1 retour chariot ;
    -> (A)+ = B = au moins une fois A ;
    -> /^chaîneDébut(B)chaîneFin$/ = une chaîne de caractères commençant par chaîneDébut, finissant par chaîneFin avec B au milieu.

    Exemple avec "chaîneDébutCeci\nest\nla\nchaîne\nquelconquechaîneFin" :
    -> A1 = "Ceci\n"
    -> A2 = "est\n"
    -> A3 = "la\n"
    -> A4 = "quelconque"
    -> B = A1+A2+A3+A4 = "Ceci\nest\nla\nchaîne\nquelconque"
  • # DOT_ALL

    Posté par  . Évalué à 4.

    Salut,

    Normalement, il faut utiliser DOT_ALL qui permet au caractère "." de matcher aussi "\n".
    Donc ça doit être quelque chose du genre "/chaîneDebut.*chaîneFin)/s"

    cf http://fr3.php.net/manual/en/reference.pcre.pattern.modifiers.php(...)
  • # Merci

    Posté par  (site web personnel) . Évalué à 1.

    Merci à vous deux, ça marche !

    C'est bien DOT_ALL (matérialisée par un "s") qu'il me manquait.

    De plus, pour information si quelqu'un tombe sur ce message en cherchant sur Google, l'option PCRE_UNGREEDY matérialisée par un "U" permet d'éviter de remplacer trop de choses quand on a plusieurs occurences à remplacer d'un seul coup.

    Exemple:
    Test chaineDebut chaineQuelconque chaineFin Salut chaineDebut chaineQuelconque2 chaineFin Test2


    On veut remplacer ce qu'il y a entre chaineDebut et chaineFin par une chaine vide.

    avec l'expression suivante:
    /chaineDebut.*chaineFin/s

    Vous obtiendrez:
    Test Test2


    Tandis qu'avec celle-ci:
    /chaineDebut.*chaineFin/sU

    Vous aurez:
    Test Salut Test2


    Que ça serve à quelqu'un !

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.