Oppure

Loading
23/02/17 15:00
domenico_rizzo
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

1;2;3;"a";"b";"c";"d";"e";"f"
3;4;5;"";"";"";"";"";""
6;7;8;"";"";"";"";"";""
9;10;11;"";"";"testo a caso

con ritorni a 
capo vari
0
";"";"";""
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 23/02/17 16:07
aaa
23/02/17 16:05
Roby94
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:
aaa
23/02/17 16:12
domenico_rizzo
@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:
1;2;3;"a";"b";"c";"d";"e";"f"
3;4;5;"";"";"";"";"";""
6;7;8;"";"";"";"";"";""
9;10;11;"";"";"testo a caso
 
con ritorni a
capo vari
0
";"";"";""
12;13;14;"";"";"";"";"";""

vorrei poter ottenere questo:

1;2;3;"a";"b";"c";"d";"e";"f"
3;4;5;"";"";"";"";"";""
6;7;8;"";"";"";"";"";""
9;10;11;"";"";"testo a caso con ritorni a capo vari 0";"";"";""
12;13;14;"";"";"";"";"";""
Ultima modifica effettuata da domenico_rizzo 23/02/17 16:18
aaa
23/02/17 16:49
Roby94
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.
aaa
23/02/17 17:08
domenico_rizzo
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:
aaa
23/02/17 18:34
domenico_rizzo
@Roby94 ho creato questo, ma non fa correttamente quello che dovrebbe. Sai dirmi dove sbaglio? :(
$rows = file("$tableName.txt");
for($i = 0; $i < count($rows); $i++) {
	$row = trim(str_replace("<br>", "$", $rows[$i]));
	$lastCh = mb_substr($row, -1);
	if ( strcmp($lastCh, "\"") != 0){
		while(true){//for($j = $i + 1; $j < count($rows); $j++){
			$j = $i + 1;
			$tempRow = trim($rows[$j]);
			$lastChRow = mb_substr($tempRow, -1);
			
			if ( strcmp($lastChRow, "\"") != 0){
				$row .= $tempRow;
			}
			else{
				$row .= "<br>";
				break;
			}
			$j++;
		}
	}
}
Ultima modifica effettuata da domenico_rizzo 23/02/17 21:53
aaa
23/02/17 22:32
Roby94
Allega un risultato e/o descrivi bene l'errore che riscontri con il tuo codice.
aaa
23/02/17 22:41
kyme
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:

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



Uso quindi la funzione preg_match_all per le espressioni regolari:

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



Per visualizzare il risultato:

echo "<pre>";
var_dump($array_uscita);
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:
it2.php.net/manual/en/…
Ultima modifica effettuata da kyme 23/02/17 22:43
aaa