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 :

Faire tourner une RegEx sur l'intégralité d'un fichier


Sujet :

Langage PHP

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut Faire tourner une RegEx sur l'intégralité d'un fichier
    Bonjour à tous!

    J'ai un projet en php contenant quelques centaines de fichiers avec du code bien sale. Du bon procédural avec le code HTML mélangé dans des fonctions de traitement, à l'ancienne, avec une mise en page à base de <table>. Bref du bonheur...

    Je souhaite dépoussiérer ce projet (dont je ne suis pas l'auteur) et effectuer un découpage MVC puis une factorisation du code. (courage, courage!)

    La première étape quand je prends un fichier c'est d'effectuer quelques manipulations de base (réécriture des balises HTML en minuscules, réécriture des include() et require(), changement de certaines classes HTML, etc...) Ces manipulations je les effectue à la main et ça me prend 10 bonnes minutes par fichier, et vu le nombre de fichiers... Donc je voudrais créer une routine, à base de RegEx, pour automatiser cette étape.

    J'ai effectué des test, j'arrive a utiliser mes RegEx sur des variables mais pas directement sur mon fichier. Voici comment je procède:

    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
    24
    25
    26
    27
    28
    29
    30
     
    // Dossier source
    $folder = 'MonDossier' . DIRECTORY_SEPARATOR;
    // Fichier source
    $file = 'testFile.php';
    // chemin complet vers mon fichier source
    $path = ROOT . $folder . $file;
     
    // Teste si le fichier existe
    if (file_exists($path)) {
        echo 'Le fichier : "' . $path . '" existe';
    } else {
        echo 'Erreur, le fichier : "' . $path . '" n&apos;existe pas';
    }
     
    // ouverture du fichier en lecture et écriture
    $handle = fopen($path, 'r+');
     
    // REGEX insensible à la casse avec '/i'
    $pattern = '/^(include|require){1}(_once)?[ ]?[\(]?[\'"](.*?)[\'"][\)]?[ ]?;/i';
    $replace = '${1}${2}W ROOT . \'${3}'.'\';';
     
    // Modification du contenu
    $action = preg_replace($pattern, $replace, $handle);
     
    // Ecriture dans le fichier
    $write = fwrite($handle, $action);
     
    // Fermeture du fichier
    fclose($path);
    La seule chose que j'obtiens comme changement sur mon fichier c'est qu'au tout début il apparaît ce message : "Resource id #3" !!

    Je crois que je n'ai pas compris comment on manipule le contenu d'un fichier...

    Voyez-vous d'où vient mon erreur et comment la réparer svp?

    Merci pour votre temps.

  2. #2
    Expert confirmé
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 713
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 713
    Par défaut
    quand vous faite "$handle = fopen", la variable contient seulement l'identifiant de la ressource, qu'il faut ensuite parcourir pour lire le contenu du fichier
    Si vous voulez lire le fichier en entier et le réécrire d'un coup je vous conseille de plutot utiliser ces fonctions :
    http://php.net/file_get_contents
    http://php.net/file_put_contents

  3. #3
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    pour ma part, j'utilise Notepad++ :

    • on peut ouvrir plusieurs fichiers en même temps (quelques centaines sans problème)
    • on peut "rechercher" / "remplacer" sur l'ensemble des fichiers ouverts, avec 3 modes de recherche, dont "expression régulière"

    Ce serait dommage de s'en priver....


    N.B. Ne dis pas de mal du "procédural "....

  4. #4
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    tout d'abord merci pour vos réponses.

    @jreaux62 : J'utilise PhpStorm qui a aussi une aide pour les RegEx. Le problème que je rencontre ne vient pas vraiment des RegEx mais plutôt du traitement du fichier.

    @mathieu : J'ai regardé les deux liens que vous m'avez proposé, j'ai fait un test mais ce n'était pas vraiment concluant. Par contre j'obtiens un début de résultat avec file() qui découpe mon fichier dans une table ce qui devrait être pratique pour le traitement ensuite.

    J'ai essayé la technique suivante :
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
     
    // Dossier source
    $folder = 'MonDossier' . DIRECTORY_SEPARATOR;
    // Fichier source
    $file = 'testFile.php';
    // chemin complet vers mon fichier source
    $path = ROOT . $folder . $file;
     
    // Teste si le fichier existe
    if (file_exists($path)) {
        echo 'Le fichier : "' . $path . '" existe';
    } else {
        echo 'Erreur, le fichier : "' . $path . '" n&apos;existe pas';
    }
     
    // découpage du fichier dans un array
    $lines = file($path);
     
    // Pattern de ma REGEX (insensible à la casse avec '/i')
    $pattern = '/^(include|require){1}(_once)?[ ]?[\(]?[\'"](.*?)[\'"][\)]?[ ]?;/i';
    // Remplacement souhaité pour chaque match
    $replace = '${1}${2} ROOT . \'${3}'.'\';';
     
    // boucle pour traiter chaque ligne du tableau
    $aAfter = array();
    foreach ($lines as $line) {
        array_push(
            $aAfter,
            array(
                preg_replace($pattern, $replace, utf8_decode($line))
            )
        );
    }
     
    // Affichage du résultat
    echo '<br>VALEUR APRES TRAITEMENT : <br>';
    var_dump($aAfter);
     
    // Fermeture du fichier
    fclose($path);
    J'ai un début de résultat intéressant, c'est à dire que pour chaque ligne j'ai bien UN traitement qui s'effectue. Malheureusement si sur une ligne j'ai deux match qui correspondent à ma RegEx, seul le premier est remplacé. A ce stade je ne comprends pas trop comment appliquer la même tâche s'il y a plusieurs occurrences.

    Voyez-vous a quel niveau mon raisonnement est biaisé? Peut-être que preg_replace() n'est pas la bonne fonction?

    Je tenterai de remplacer l'intégralité du fichier par le nouveau résultat une fois que celui-ci sera bon, pour le moment je me concentre surtout sur le traitement.

    Merci pour votre attention.

  5. #5
    Invité
    Invité(e)
    Par défaut
    J'utilise PhpStorm qui a aussi une aide pour les RegEx...
    Je ne parlais pas d'aide mais bien de traitement.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    $pattern = '/................/Ui';
    U pour 'ungreedy".


  6. #6
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    @jreaux62 : Bonjour et merci! En effet Notepad++ et PhpStorm font tout les deux du traitement de RegEx, et je les utilise aussi, mais le but de ce que je veux faire avec le code en question c'est d'automatiser plusieurs traitement à suivre. (Environ 5 traitements avec 5 RegEx différentes).
    Je viens de tester l'option de recherche PCRE_UNGREEDY mais je n'ai pas vraiment constaté de différence.

    Mais je ne m'avoue pas encore vaincu.

  7. #7
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Tu te compliques la vie (et le code) en découpant ton fichier en lignes...

    Citation Envoyé par mathieu Voir le message
    Si vous voulez lire le fichier en entier et le réécrire d'un coup je vous conseille de plutot utiliser ces fonctions :
    http://php.net/file_get_contents
    http://php.net/file_put_contents
    Quant à tes array pattern / replace :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
            $file_content_clean = preg_replace($aPattern, $aReplace, $file_content);
    C'est quand même plus simple et clair, non ?
    Dernière modification par Invité ; 16/11/2017 à 09h24.

  8. #8
    Membre averti
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Janvier 2012
    Messages
    49
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Janvier 2012
    Messages : 49
    Par défaut
    Bonjour à tous,

    J'ai lu attentivement (enfin je l'espère) ce que vous m'avez dit et j'ai essayé de le mettre en pratique. J'utilise maintenant file_get_contents() et je réécris mon résultat dans un autre fichier. J'ai également affiné ma RegEx suite à vos conseils communs.

    C'est en effet plus simple et plus propre même s'il reste encore quelques détails à perfectionner.

    J'aimerais savoir s'il est possible (et comment surtout parce que j'ai fait des tests mais rien ne donne de résultats concluants) de faire un traitement sur un groupe capturant pendant le preg_replace() ?

    Voici mon code:
    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
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
     
    // Racine du source
    define('ROOT', __DIR__ . DIRECTORY_SEPARATOR);
    // Dossier source
    $folder = 'ressources' . DIRECTORY_SEPARATOR;
    // Fichier source
    $file = 'testFile.php';
    // Chemin complet de mon fichier source
    $path = ROOT . $folder . $file;
     
    // Teste si le fichier existe
    if (file_exists($path)) {
        echo 'Le fichier : "' . $path . '" existe';
    } else {
        echo 'Erreur, le fichier : "' . $path . '" n&apos;existe pas';
    }
     
    // Le contenu du fichier est mis en variable
    $fileContent = file_get_contents($path);
     
    // Pattern pour la RegEx
    $aPattern = '/((?:include|require)(?:_once)?)\s*\(?(?:[\'"])(.*?)(?:[\'"])[\)]?\s*[;]/i';
     
    // Replace qui correspond à mon pattern
    $aReplace = '${1} ROOT . \'${2}'.'\';';
     
    // J'effectue mon traitement de RegEx
     $fileContentClean = preg_replace($aPattern, $aReplace, $fileContent);
     
    // Déclaration de mon fichier cible
    $cleanFile = 'clean.php';
     
    // Chemin complet du fichier cible
    $newPath = ROOT . $folder . $cleanFile;
     
    // Ouverture du fichier cible
    $f = fopen($newPath, 'r+');
     
    // Ecriture dans le fichier cible
    fwrite($f, $fileContentClean);
     
    // Fermeture du fichier cible
    fclose($f);
    Pour finir donc je voudrais faire un strtolower() sur mon groupe capturant ${1}. J'ai voulu faire quelque chose dans le genre :
    $aReplace = strtolower(${1}) ROOT . \'${2}'.'\';';

    Mais cela provoque des erreurs. Est-ce possible et comment procéder?

    Merci à vous pour vos conseils, je crois que je n'aurais jamais réussi seul à faire quelque chose de potable.

  9. #9
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Pourquoi t'acharnes-tu à mettre des accolades là où elles ne sont pas utiles ??

    Relis la doc :



    replacement
    [...]
    replacement peut contenir des références de la forme \\n ou, (depuis PHP 4.0.4) $n. Cette dernière forme est recommandée.
    [...]
    Lorsque vous travaillez avec un masque de remplacement où une référence arrière est directement suivie par un nombre [...]
    Dans ce cas, la solution est d'utiliser la syntaxe \${1}1. Cela créera une référence arrière isolée $1, suivi du nombre littéral 1.

Discussions similaires

  1. Faire tourner une image sur son axe
    Par choupinou22 dans le forum Mise en page CSS
    Réponses: 2
    Dernier message: 04/07/2015, 18h49
  2. Faire tourner une appli XP sur W7
    Par pierrot67 dans le forum Débuter
    Réponses: 4
    Dernier message: 07/09/2012, 14h28
  3. Réponses: 7
    Dernier message: 15/07/2011, 06h35
  4. Faire tourner une forme sur elle-même
    Par Suditidus dans le forum ActionScript 3
    Réponses: 1
    Dernier message: 14/06/2010, 12h05

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