Newsgroup: it.comp.www.php
Titolo: Problemino con stringhe

Buongiorno a tutti...
Ho un file di testo che proviene da un decoder. Questo file viene aggiornato
ogni 5 minuti, ovvero vengono appese delle nuove righe.
Dopo aver depurato il file da (quasi) tutto quello che non mi serve, ciò che
riesco ad ottenere, dopo qualche elaborazione, è questo:
----------------------------------------------------------------------------
---------------------
Corsa numero 1 ------------------------------
- 1 -UNO ELCANTO DELL`ARSO 1.19.1
- 2 -DIECI ELGA GA 19.4
- 3 -QUATTRO ECCOLO LUIS 19.8
- 4 -DUE EVASA D`ITALIA 19.8
- 5 -CINQUE EKK 20.4
- 6 -NOVE EXPLOIT BI 20.5
- 7 -SEI EFESTO DEL RONCO 22.2
- 8 -OTTO EXCALIBUR GAR
Corsa numero 2 ------------------------------
- 1 -QUATTRO CHARMANTE 1.16.4
- 2 -TRE CHELSY LADY 16.8
- 3 -DUE COSMIC CANF 17.1
- 4 -UNO CLAUDIO GIANFI 17.2
- 5 -CINQUE CASTELCOMBERTO 17.5
- 6 -SETTE CIRIBIX 17.6
- 7 -SEI CARISSIMA MARA R.P.
Corsa numero 3 ------------------------------
- 1 -SEI DEEP FEELING LF 1.15.4
- 2 -DUE DIAVOLONE LUIS 15.4
- 3 -TRE D`ANDRADE FONT 15.4
- 4 -SETTE DIAVOLO IZ 15.6
- 5 -CINQUE DOUSSIE` HOLZ 15.7
- 6 -UNO DELANTE KING 18.1
- 7 -QUATTRO DALIDA` LUIS R.P.
----------------------------------------------------------------------------
--------------
Ovviamente questo è quanto si vede dal browser: l'html è leggermente
diverso, ma credo che la sostanza non cambi, in quanto vengono coinvolti
solo gli spazi che l'html si mangia. Ogni riga è chiusa da un <br>.
Il mio problemone è che queste righe vanno esplose, per riempire i campi di
un db, quindi alcuni caratteri vanno esclusi ed altri mantenuti, ma non
essendoci delimitatori fissi non so come fare. Nella fattispecie dovrei
ottenere tre valori:
1) il numero iniziale, scartando trattini e spazi
2) il nome, che è quello che si vede in lettere, depurato dalla parte
iniziale che indica sempre un numero in lettere, e della parte finale
3) il valore numerico finale, che però a volte può anche comprendere la
dicitura RIT, R.P., ed altre amenità, comunque codificate.
In sostanza, prendendo la riga "- 1 -UNO ELCANTO DELL'ARSO 1.19.1", vorrei
ottenere tre variabili:
a=1
b=ELCANTO DELL'ARSO
c=1.19.1
Ci ho picchiato la testa per un po', ma non sono ancora venuto a capo di
nulla.... Se qualcuno ha qualche idea, suggerimento, indicazione, mi farebbe
una grossa cortesia.
Grazie, Carlo.

 una grossa cortesia.
preg_match("/^-\s*([0-9]+)\s*-(.*)\s+([^ ])+$/",$riga, $m);
in $m[1],$m[2],$m[3] dovresti trovare quello cercato...
(non provato)
-- 
http://diebspiel.de/index.php?id=1930

 posted this:



infatti (ma non ancora provato)
preg_match("/^-\s*([0-9]+)\s*-(.*)\s+([^ ]+)$/",$riga, $m);
-- 
http://diebspiel.de/index.php?id=1930

 ha scritto nel messaggio
news:zPMxb.3103$yq1....@tornado.fastwebnet.it...

Infatti funziona, a parte un piccolo particolare che però vorrei risolvere
da solo.... Contavo di evitare le ereg, ma il fine giustifica sempre i
mezzi.
Saresti così gentile da spiegarmi il criterio utilizzato per il match..?
Leggendo su vari manuali, l'utilizzo di questa funzione è sempre nebuloso e
magari con un piccolo aiuto mi si spalanca un mondo nuovo :-)
Grazie, comunque, per la disponibilità.... Se non ci fosse il NG sarei
rovinato!
Carlo.

 magari con un piccolo aiuto mi si spalanca un mondo nuovo :-)
Allora spulciamo e facciamo un minitutorial
/^-\s*([0-9]+)\s*-(.*)\s+([^ ]+)$/
/ inzio della espressione, deve anche finire con quello,
  possono esser anche altri caratteri [spesso vedi = # $],
  il carattere usato deve essere mascherato con \ se
  viene usato come carattere di matching: \/
^ inzio stringa (se no: espressione viene provata su tutte le posizioni)
- carattere -
\s* spazi/tab, 0 o piu (*)
([0-9]+) gruppo con classe di cifre, minimo uno (+)
 attenzion al - qui significa un range di caratteri.
\s*  come prima
- come prima
(.*) qualsiasi pezzo di stringa quindi determinato dalla fine della espression
\s+ almeno uno spazio
([^ ]+) gruppo di NON spazio, nel [] il ^ prende un significato diverso che al
di fuori dalla classe di caratteri
$ fine della stringa (non sarebbe buono usarlo se passi tante righe ed usi
preg_match_all(), e si metterebbe un \n ad esempio)
/ fine espressione (qui possono adesso seguire modificatori, ma non servono
nel tuo caso, i piu utili sono
  i (ignora maiuscolo/minuscolo)
 U (espressione piu breve che fa match)
 s (tratta newline come uno spazio))
 e (esegue codice, utile per preg_replace, fa una cosa tipo eval su stringhe)
i tre gruppi ( ) ( ) ( ) vengono messi come risultato nel array, o possono
essere usati come back reference.

 > Leggendo su vari manuali, l'utilizzo di questa funzione è sempre

Beh...Alla faccia del minitutorial! Ti ringrazio molto della spiega
esauriente.... L'unica cosa che avevo capito era che nel criterio per il
match, ciò che è contenuto all'interno delle ( ) contribuisce a valorizzare
l'elemento dell'array, tranne l'elemento [0] che è la stringa intera in cui
si cerca: mi domandavo a cosa servissero tutti gli altri parametri, visto
che nel manuale on-line non se ne fa menzione.
Il confronto avviene sequenzialmente da sinistra a destra? Nel caso nostro
dovrebbe funzionare così, se ho capito bene:
cerca il carattere -, gli spazi/tab, gli *, i numeri da o a 9 (almeno uno),
gli spazi/tab, gli *, il carattere -, qualsiasi stringa, almeno uno spazio,
gruppo di non spazio.
assegna agli elementi [1], [2], [3] i valori ricavati da quanto è nelle ( )
Quello che non capisco è il significato di ([^]+), che dovrebbe essere
quello che nel mio caso individua la sequenza numerica alla fine della
stringa, ovvero il terzo elemento dell'array, ma sarà meglio che vada a
vedermelo personalmente.
Ti ringrazio ancora moltissimo, Carlo.

 vedermelo personalmente.
No hai solo numeri nel tuo caso... se no: [0-9.]+
vedi anche l'operatore |, probabilmente ti crea una espressione piu' robusta.
Link molto, molto utile (inglese) 
http://www.regexlib.com/
-- 
http://diebspiel.de/index.php?id=2288

 
http://diebspiel.de/index.php?id=2288
Letto tutto.... Capito il 90%... Soprattutto ho capito di aver sparato delle
cavolate nel mio precedente messaggio :-)
Grazie ancora: ora credo di aver definitivamente finito di rompere (riguardo
questo argomento, eh...)
Carlo.

 vedi anche l'operatore |, probabilmente ti crea una espressione piu'
robusta.
< ROTTURA DI SCATOLE >
Rompo ancora un momentino, perchè non mi è ben chiara qualche cosina...
Il criterio (.*) e (\w{0}) non sono la stessa cosa..? Sembrerebbe di no, a
prove fatte
Se voglio identificare esattamente due spazi nella stringa, posso usare
\s{2}...?
Il problema è che io, dopo il numero iniziale identificato da [0-9]+, devo
spezzettare la stringa ancora in due parti, prima della parte finale, parti
che sono sempre separate da due spazi, e di cui la prima è sempre un numero
espresso in lettere. Inoltre la parte finale della stringa non sempre
contiene caratteri senza spazi: a volte contiene una frase del tipo RIT IN
CORSA che, con il criterio che mi hai suggerito, entra a far parte del nome
precedente.
Con un esempio, mi posso trovare due stringhe del tipo:
- 1 -SEI  PINCO PALLINO                     1.10.1
- 1 -SEI  PINCO PALLINO                       RIT IN CORSA
Ammettiamo di dover esplodere la stringa in tutti i suoi componenti e
valorizzare una variabile: come potrebbe essere costruito il criterio...?
</ROTTURA DI SCATOLE>
Grazie, Carlo.