Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
PHP - Formattazione corretta in un file di testo
Forum - PHP - Formattazione corretta in un file di testo

Pagine: [ 1 2 ] Precedente | Prossimo
Avatar
domenico_rizzo (Normal User)
Pro


Messaggi: 90
Iscritto: 27/07/2015

Segnala al moderatore
Postato alle 16:00
Giovedì, 23/02/2017
Salve avrei bisogno di un aiuto di logica principalmente che di codice.
Mettiamo il caso abbia un file di testo formato in questo modo:
intero;intero;intero;stringa;stringa;stringa;stringa;stringa;stringa
Codice sorgente - presumibilmente Plain Text

  1. 1;2;3;"a";"b";"c";"d";"e";"f"
  2. 3;4;5;"";"";"";"";"";""
  3. 6;7;8;"";"";"";"";"";""
  4. 9;10;11;"";"";"testo a caso
  5.  
  6. con ritorni a
  7. capo vari
  8. 0
  9. ";"";"";""
  10. 12;13;14;"";"";"";"";"";""


premettendo che ricavo ogni riga del file mettendola in un array di stringhe con $rows = file("fileName.txt");, il mio problema e' cercare di eliminare quelle righe che DOVREBBERO far parte della stringa ma a causa dei ritorni a capo mi sfalsa tutto; cioe' alla fine vorrei ottenere ogni riga pulita (magari sostituiti con il tag <br> ).
Avete idee su come risolvere questa cosa?? :-|

Ultima modifica effettuata da domenico_rizzo il 23/02/2017 alle 17:07
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 17:05
Giovedì, 23/02/2017
Puoi scegliere di proseguire in molte direzioni:
-In fase di creazione del file, (sempre che sia tu a crearlo) sostituisci \n con un carattere di escape alternativo, cosi da non dover cambiare approccio di lettura.
-Cambi approccio ed effetti un parsing carattere per carattere per identificare le varie parti del file (difficile)
-Se non hai motivo di credere che il file diventi di grandi dimensioni lo carichi tutto in memoria come stringa e mediante regex ne estrai i dati
-Ti affidi ad un altro sistema di serializzazione, sempre nel caso tu possa scegliere la codifica del file(XML, json, ecc). PHP mette a disposizione delle funzioni di facile utilizzo per questo compito (vedi serialize) (facile)
Possiamo andare avanti tutto il giorno :asd:

PM Quote
Avatar
domenico_rizzo (Normal User)
Pro


Messaggi: 90
Iscritto: 27/07/2015

Segnala al moderatore
Postato alle 17:12
Giovedì, 23/02/2017
@Roby94 Mhm quante idee :rotfl:
Allora cominciamo ad escluderne alcune:
il file non lo creo io, ma mi viene gia' dato cosi' quindi prendilo come buono in questo stato.
Avevo poi pensato ad un parsing carattere per carattere in modo tale da verificare che se il primo carattere di ogni riga e' un possibile numero allora accoda la stringa corrente a quella precedente; purtroppo ci sono casi in cui e' presente un ritorno a capo seguito da un numero, quindi una riga potrebbe iniziare come numero anche se tecnicamente fa parte della stringa.
Per gli altri casi non ho ben capito se si possono attuare ora che mi sono spiegato meglio diciamo.
Dimmi te 8-|


p.s. fai conto che il mio scopo e' creare un nuovo file con tutto il testo precedente formattato correttamente (sempre attraverso php)

quindi da questo:
Codice sorgente - presumibilmente Plain Text

  1. 1;2;3;"a";"b";"c";"d";"e";"f"
  2. 3;4;5;"";"";"";"";"";""
  3. 6;7;8;"";"";"";"";"";""
  4. 9;10;11;"";"";"testo a caso
  5.  
  6. con ritorni a
  7. capo vari
  8. 0
  9. ";"";"";""
  10. 12;13;14;"";"";"";"";"";""


vorrei poter ottenere questo:

Codice sorgente - presumibilmente Plain Text

  1. 1;2;3;"a";"b";"c";"d";"e";"f"
  2. 3;4;5;"";"";"";"";"";""
  3. 6;7;8;"";"";"";"";"";""
  4. 9;10;11;"";"";"testo a caso con ritorni a capo vari 0";"";"";""
  5. 12;13;14;"";"";"";"";"";""


Ultima modifica effettuata da domenico_rizzo il 23/02/2017 alle 17:18
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 17:49
Giovedì, 23/02/2017
La strada che seguirei da programmatore sarebbe il parsing che possiamo definire C-like, leggo un carattere e lo interpreto, ogni volta che incontro che incontro l'ottavo ; so che il prossimo parametro è l'ultimo della riga quindi dopo il secondo " mi aspetto uno \n per segnare la fine del record quindi sono certo che sia quello lo \n da considerare.
Da pigro invece la farei molto più semplice, per ogni riga controllo che l'ultimo carattere sia " se non lo è so che c'è stato un erroneo \n che non è il terminatore di record, quindi vi accodo la riga successiva e continuo cosi finché non trovo " seguito da \n.

PM Quote
Avatar
domenico_rizzo (Normal User)
Pro


Messaggi: 90
Iscritto: 27/07/2015

Segnala al moderatore
Postato alle 18:08
Giovedì, 23/02/2017
Mhm direi che come algoritmi risolvono entrambi il mio problema!Ti ringrazio :k:
Provero' a realizzarlo e nel caso dovessi trovare degli errori che portino al suo non risolvimento, te lo posto direttamente qua sperando tu possa aiutarmi :hail:

PM Quote
Avatar
domenico_rizzo (Normal User)
Pro


Messaggi: 90
Iscritto: 27/07/2015

Segnala al moderatore
Postato alle 19:34
Giovedì, 23/02/2017
@Roby94 ho creato questo, ma non fa correttamente quello che dovrebbe. Sai dirmi dove sbaglio? :(
Codice sorgente - presumibilmente Php

  1. $rows = file("$tableName.txt");
  2. for($i = 0; $i < count($rows); $i++) {
  3.         $row = trim(str_replace("<br>", "$", $rows[$i]));
  4.         $lastCh = mb_substr($row, -1);
  5.         if ( strcmp($lastCh, "\"") != 0){
  6.                 while(true){//for($j = $i + 1; $j < count($rows); $j++){
  7.                         $j = $i + 1;
  8.                         $tempRow = trim($rows[$j]);
  9.                         $lastChRow = mb_substr($tempRow, -1);
  10.                        
  11.                         if ( strcmp($lastChRow, "\"") != 0){
  12.                                 $row .= $tempRow;
  13.                         }
  14.                         else{
  15.                                 $row .= "<br>";
  16.                                 break;
  17.                         }
  18.                         $j++;
  19.                 }
  20.         }
  21. }


Ultima modifica effettuata da domenico_rizzo il 23/02/2017 alle 22:53
PM Quote
Avatar
Roby94 (Member)
Guru


Messaggi: 1170
Iscritto: 28/12/2009

Segnala al moderatore
Postato alle 23:32
Giovedì, 23/02/2017
Allega un risultato e/o descrivi bene l'errore che riscontri con il tuo codice.

PM Quote
Avatar
kyme (Normal User)
Newbie


Messaggi: 1
Iscritto: 31/08/2015

Segnala al moderatore
Postato alle 23:41
Giovedì, 23/02/2017
Come strategia efficace per risolvere il problema si potrebbero usare le espressioni regolari. Ecco il mio codice, che sembra funzionare con i dati che hai fornito.

I dati campione sono questi, inseriti in una variabile:

Codice sorgente - presumibilmente Plain Text

  1. $testo_entrata = <<<EOD
  2. 1;2;3;"a";"b";"c";"d";"e";"f"
  3. 3;4;5;"";"";"";"";"";""
  4. 6;7;8;"";"";"";"";"";""
  5. 9;10;11;"";"";"testo a caso
  6.  
  7. con ritorni a
  8. capo vari
  9. 0
  10. ";"";"";""
  11. 12;13;14;"";"";"";"";"";""
  12. EOD;




Uso quindi la funzione preg_match_all per le espressioni regolari:

Codice sorgente - presumibilmente Plain Text

  1. preg_match_all("/(\d+);(\d+);(\d+);[\"](.*?)[\"];[\"](.*?)[\"];[\"](.*?)[\"];[\"](.*?)[\"];[\"](.*?)[\"];[\"](.*?)[\"]/s", $testo_entrata, $array_uscita, PREG_SET_ORDER);




Per visualizzare il risultato:

Codice sorgente - presumibilmente Plain Text

  1. echo "<pre>";
  2. var_dump($array_uscita);
  3. echo "</pre>";




L'espressione regolare che ho usato è abbastanza grezza ma si può affinare secondo necessità. Importante è la presenza del modificatore finale della regex: s
Esso permette di includere gli "a capo" nella ricerca dei caratteri. Riferimenti al riguardo:
http://it2.php.net/manual/en/reference.pcre.pattern.modifi ...

Ultima modifica effettuata da kyme il 23/02/2017 alle 23:43
PM Quote
Avatar
domenico_rizzo (Normal User)
Pro


Messaggi: 90
Iscritto: 27/07/2015

Segnala al moderatore
Postato alle 15:47
Venerdì, 24/02/2017
@kyme su quel codice effettivamente funziona ma sul mio file (che contiene dati sensibili e quindi non posso farvelo mostrare) non mi stampa nulla praticamente :d

@Roby94 ora vi metto il mio codice e il risultato che produce (mascherando i dati)
Codice sorgente - presumibilmente Php

  1. $rows = file("$tableName.txt");
  2.                 echo "<html><head> <style>
  3.                         body {
  4.                                 margin: 10;
  5.                         }
  6.                         div, pre {
  7.                                 white-space: nowrap; // will prevent the default wrapping of text to next line
  8.                                 overflow-x: auto;
  9.                                 width: 100vw;
  10.                                 height: 100vh;
  11.                         }
  12.                         h3{display: inline;}
  13.                         .no{color: red;}
  14.                         .ok{color: green;}</style></head><body><pre>";
  15.                 for($i = 0; $i < count($rows); $i++) {
  16.                         $row = trim(str_replace('<br>', '$', $rows[$i]));
  17.                         $lastCh = mb_substr($row, -1);
  18.                         //echo '$row <span class='no'> [$lastCh]</span><br>';
  19.                         if ( strcmp($lastCh, '\'') != 0){
  20.                                 $k = 0;
  21.                                 for($j = $i + 1; $j < count($rows); $j++){
  22.                                         $tempRow = trim($rows[$j]);
  23.                                         $lastChRow = mb_substr($tempRow, -1);
  24.                                         //echo '[$tempRow] [$lastChRow]<br>';
  25.                                         if ( strcmp($lastChRow, "\"") != 0){
  26.                                                 //echo 'entrato<br>';
  27.                                                 $row .= ($tempRow . "<br>");
  28.                                                 $k++;
  29.                                         }
  30.                                         else{
  31.                                                 $row = trim($row);
  32.                                                 $row .= "$";
  33.                                                 $i += $k;
  34.                                                 break;
  35.                                         }
  36.                                 }
  37.                         }
  38.                                         $row = str_replace(array("\n\r", "\n", "\r"), "", $row);
  39.                         echo "<span class='ok'>$row</span>-----------------<br>";
  40.                 }
  41.                 echo '</pre></body></html>';


P.S. Screenshot del risultato in allegato

Ogni riga dovrebbe iniziare dal segno arancione e finire al cancelletto rosso { quello prima del successivo segno arancione   }  ma come vedete sballa completamente sulle righe con i ritorni a capo. Come dovrei correggere il codice sopra?


domenico_rizzo ha allegato un file: screen.jpg (160910 bytes)
Clicca qui per guardare l'immagine

Ultima modifica effettuata da domenico_rizzo il 24/02/2017 alle 15:52
PM Quote
Pagine: [ 1 2 ] Precedente | Prossimo