web-dev-qa-db-fra.com

Parcourez chaque ligne d'une chaîne dans PHP

J'ai un formulaire qui permet à l'utilisateur de télécharger un fichier texte ou de copier/coller le contenu du fichier dans une zone de texte. Je peux facilement différencier les deux et mettre celui qu'ils ont entré dans une variable chaîne, mais où vais-je à partir de là?

Je dois parcourir chaque ligne de la chaîne (de préférence, ne pas m'inquiéter des lignes nouvelles sur différentes machines), m'assurer qu'il ne contient qu'un seul jeton (sans espaces, tabulations, virgules, etc.), assainir les données, puis générer une requête SQL basé sur toutes les lignes.

Je suis un assez bon programmeur. Je connais donc l’idée générale de la façon de le faire, mais cela fait tellement longtemps que je n’ai pas travaillé avec PHP) que j’ai l’impression de chercher les mauvaises choses et Ainsi, je trouve des informations inutiles. Le problème essentiel que je rencontre est que je veux lire le contenu de la chaîne ligne par ligne. Si c'était un fichier, ce serait facile.

Je suis surtout à la recherche de fonctions utiles PHP, pas d'algorithme pour le faire. Vous avez des suggestions?

113
Topher Fangio

preg_split la variable contenant le texte et parcourez le tableau retourné:

foreach(preg_split("/((\r?\n)|(\r\n?))/", $subject) as $line){
    // do stuff with $line
} 
165
Kyril

Je voudrais proposer une alternative significativement plus rapide (et économe en mémoire): strtok plutôt que preg_split.

$separator = "\r\n";
$line = strtok($subject, $separator);

while ($line !== false) {
    # do something with $line
    $line = strtok( $separator );
}

Pour tester les performances, j'ai répété 100 fois sur un fichier test de 17 000 lignes: preg_split a pris 27,7 secondes, alors que strtok a pris 1,4 seconde.

Notez que si le $separator est défini comme "\r\n", strtok séparera chaque caractère - et à partir de PHP 4.1.0, sautera les lignes/jetons vides.

Voir l'entrée du manuel strtok: http://php.net/strtok

137
Erwin Wessels

Si vous avez besoin de gérer les nouvelles lignes dans différents systèmes, vous pouvez simplement utiliser le PHP constante prédéfinie PHP_EOL (http://php.net/manual/en/reserved.constants.php) et simplement utiliser éclaté éviter les frais généraux du moteur des expressions régulières.

$lines = explode(PHP_EOL, $subject);
93
FerCa

C'est trop compliqué et moche, mais à mon avis c'est la voie à suivre:

$fp = fopen("php://memory", 'r+');
fputs($fp, $data);
rewind($fp);
while($line = fgets($fp)){
  // deal with $line
}
fclose($fp);
18
pguardiario

La réponse de Kyril est la meilleure compte tenu du fait que vous devez être capable de gérer les nouvelles lignes sur différentes machines.

"Je recherche principalement des fonctions utiles PHP, pas un algorithme expliquant comment le faire. Des suggestions??"

Je les utilise beaucoup:

  • explode () peut être utilisé pour scinder une chaîne de caractères en un tableau, à partir d'un seul délimiteur.
  • implode () est l'équivalent de explode, pour passer du tableau à la chaîne.
4
Joe Kiley
foreach(preg_split('~[\r\n]+~', $text) as $line){
    if(empty($line) or ctype_space($line)) continue; // skip only spaces
    // if(!strlen($line = trim($line))) continue; // or trim by force and skip empty
    // $line is trimmed and Nice here so use it
}

^ c’est ainsi que vous cassez les lignes correctement, compatible multiplate-forme avec Regexp :)

4
CodeAngry

Problèmes de mémoire potentiels avec strtok:

Dans la mesure où l’une des solutions suggérées utilise strtok, elle n’indique malheureusement pas de problème de mémoire potentiel (même si elle prétend être efficace en termes de mémoire). Lorsque vous utilisez strtok selon le manuel , le:

Notez que seul le premier appel à strtok utilise l’argument string. Chaque appel ultérieur à strtok nécessite uniquement le jeton à utiliser , car il garde une trace de sa position dans la chaîne en cours.

Pour ce faire, vous chargez le fichier dans la mémoire. Si vous utilisez des fichiers volumineux, vous devez les vider si vous avez terminé de parcourir le fichier en boucle.

<?php
function process($str) {
    $line = strtok($str, PHP_EOL);

    /*do something with the first line here...*/

    while ($line !== FALSE) {
        // get the next line
        $line = strtok(PHP_EOL);

        /*do something with the rest of the lines here...*/

    }
    //the bit that frees up memory
    strtok('', '');
}

Si vous ne vous occupez que de fichiers physiques (par exemple, datamining):

Selon le manuel , vous pouvez utiliser la commande file pour le téléchargement de fichier:

 //Create the array
 $lines = file( $some_file );

 foreach ( $lines as $line ) {
   //do something here.
 }
3
AbsoluteƵERØ