Newsgroup: it.comp.www.php
Titolo: Aiuto regexpr

tempo fà ho già postato una domanda del genere e mi avete aiutato molto 
gentilmente fornendomi le spiegazioni necessarie.
Purtroppo quella espressione che mi avete dato non è più adatta perchè 
il mio cliente non rispetta le specifiche quando mi invia i file da 
inserire.... insomma tocca che io mi adatti ai suoi file.
in pratica lui ha un DB in cobol e io devo inserirgli gli articoli in un 
DB mysql tramite un form HTML.
Ho realizzato un form che uploada un file di testo secondo il seguente 
schema:
CODICE;DESCRIZIONE;QUANTITA;PREZZO;PROFILO;CATEGORIA;PERIODO;REPARTO;RAGGRUPPAMENTO;
dove:
CODICE è composta da 2 stringhe non nulle di caratteri separate da un 
numero indefinito di spazi.
DESCRIZIONE una stringa non vuota
QUANTITA: un numero indefinito di cifre senza virgola
PREZZO: un numero indefinito di cifre concatenate con un "." concatenate 
con un numero indefinito di cifre
PROFILO: qualsiasi cosa anche una stringa vuota
CATEGORIA: qualsiasi cosa anche una stringa vuota
PERIODO: una stringa di testo concatenata con un numero indefinito di 
spazi concatenata con 4 cifre esatte (l'anno)
REPARTO: una stringa qualsiasi non vuota
RAGGRUPPAMENTO: una stringa qualsiasi non vuota
so che in realtà non è complicato ma con le espressioni regolari non ci 
azzecco proprio
Grazie a chi vorrà aiutarmi
Alesi_27

 inserire.... insomma tocca che io mi adatti ai suoi file.
[CUT]
ne ho buttato giu una, mi sembra funzionare...
la posto se volete commentarla (o correggerla!) o se vi è utile per 
adattarla a qualche scopo
"/^\s*[?; ]+\s+[^; ]+\s*;[^;]+;\d+;\d+\.\d+;[^;]*;[^; 
]+\s+[\d]{4,4};[^;]*;[^;]+:[^;]+;$/"
grazie
ciao
Alesi_27

CODICE;DESCRIZIONE;QUANTITA;PREZZO;PROFILO;CATEGORIA;PERIODO;REPARTO;RAGGRUPPAMENTO;
Se usi explode(), forse fai prima e meglio :-)
Leonardo

 Leonardo
era mia intenzione usare explode infatti.
Il problema è che devo verificare la validità di quello che c'è scritto. 
Con explode non si può, a meno di fare una regexpr poi per ogni singolo 
pezzo (il che equivale in definitiva a farne una per tutta la riga)
ciao
Alesi_27

 pezzo (il che equivale in definitiva a farne una per tutta la riga)
Ma sarebbe molto piu' efficiente e soprattutto leggibile usare
explode/split e di fare _dopo_ il controllo con preg/ctype.


wrote:

Pero' IMHO cosi' "debugghi" meglio. Pero':
<?
	// CODICE NON TESTATO -- CAVEAT EMPTOR
	exit('Editing this code voids the warranty');
	// Tipi standard, tanto per fare puzzo
	$STR = '[A-Z]';	// Oppure [A-Za-z], ecc.
	$NUM = '[0-9]';
	$ALNUM = '[A-Z_0-9]';
	$CHAR = '[^;]';
	$SPAZIO = "[ \t]";
	$NONVUOTA = '+';
	$QUALSIASI= '*';
	$PUNTO = '\\.';
	$SPAZI = $SPAZIO . $NONVUOTA;
	// In un mondo ideale, *qualsiasi* cosa faccia il fornitore del
	// file, ce la caviamo modificando solo ed esclusivamente $flds
	// (o al limite le definizioni subito sopra)
	$flds = array(
		'codice'	=> "$STR$NONVUOTA$SPAZI$STR$NONVUOTA",
		'descrizione'	=> "$STR$NONVUOTA",
		'quantita'	=> "$NUM$NONVUOTA",
		'prezzo'	=> "$NUM$NONVUOTA$PUNTO$NUM$NONVUOTA",
		'profilo'	=> "$STR$QUALSIASI",
		'categoria'	=> "$STR$QUALSIASI",
		'periodo'	=> "$STR$SPAZIO+$NUM$NUM$NUM$NUM"
		'reparto'	=> "$STR$NONVUOTA",
		'raggrupp'	=> "$STR$NONVUOTA",
	);
	// Modifiche fini, campo per campo
	$repl = array(
		'codice'	=>
array("($STR$NONVUOTA)$SPAZI($STR$NONVUOTA)", "\1|\2",
		// ...
	);
	$metaquery = '';
	foreach($flds as $fld => $regexp)
		$metaquery .= '(' . $regexp . ');';
	// ...
	// Analisi di $riga (non sindachiamo sul come ci procuriamo
	// $riga)
	if (ereg($metaquery, $riga, $gregs))
	{
		// Modo lento (preg_replace per fare prima, $repl per
		// maggiore flessibilita'
		$comma = '';
		$sql = '';
		$i   = 1;
		foreach($flds as $fld => $regexp)
		{
			$sql .= $comma."'". AddSlashes($gregs[$i]) ."'";
			$comma = ', ';
			$i++;
		}
		SQLExec($conn, "INSERT INTO...VALUES($sql);");
	}
	else
	{
		// Riga che non matcha.
		$fields = explode(';', $riga);
		print "Riga $rownum non corrispondente<br/>";
		print "<ul>";
		$i = 0;
		foreach($flds as $fld => $regexp)
		{
			if (!eregi("^$regexp\$", $fields[$i]))
			{
				print "<li>Il campo <i>$fld</i> vale
'$fields[$i]', che non corrisponde alla espressione regolare
'$regexp'.</li>";
			}
			$i++;
		}
		print "</ul>";
	}
Leonardo

 Leonardo
ti ringrazio davvero per lo script, lo proverò sicuramente!
:)
ciao
Alesi_27

 
in effetti con quella che ho scritto per processare 13'000 righe ci 
mette mezzo secolo circa.
Effettivamente a pensarci perde efficienza se il match deve cercarlo su 
una stringa così lunga, conviene spezzarla in sottopezzi (azz devo 
riscrivere il codice :-p)
inoltre non avrei bisogno dei [^;] (non ;) in quanto mi verrebbero 
eliminati dall'explode.
Proverò, chissà che riesca ad inserire tutti e 13'000 gli articoli in un 
solo file senza spezzarlo in pezzi
grazie :D
ciao
Alesi_27