Newsgroup: it.comp.www.php
Titolo: problema regexp

salve ho un problema da risolvere con le regexp solo non riesco
ho un file con n linee
ogni linea č cosě formattata
$line1 = "123456 "7""  "abcdefeerej" "ancora altro"
in pratica io vorrei ottenere per ogni linea
una cosa del genere
$arr[0] = "123456 "7"";
$arr[1] = "abcdefeerej";
$arr[1] = "ancora altro"
il numero di spazio fra una fra e l'altra non č sempre uguale ho provato 
con
$arr= explode('"', $line1 );
e va ma si incasina quando ci sono " innestati
grazie
ciao
--
The framework for develoment user interface on application web-based
http://sourceforge.net/projects/rdmyframework/
 

il numero di spazio fra una fra e l'altra non è sempre uguale
Allora si direbbe un lavoro su misura per preg_split().
Leonardo
-- 
Dawn is near, the time is short (Human aircraft! Hard to port!)
We eight reindeers of the night work as one in silent flight.
Let not one damn house pass by (Who taught that guy how to fly?)
Each year sees more girls and boys: how many of them can we bring toys?


inizio scusarmi per il titolo non tanto chiaro ... cmq
Si ci sono arrivato pure però non riesco a trovare come farlo


 Si ci sono arrivato pure però non riesco a trovare come farlo
Banale banale non è, in effetti: hai un numero non meglio precisato di
spazi fra gli apici "delimitatori" e altri spazi (fra una parola e
un'altra) all'interno degli stessi. Io, per non saper né leggere né
scrivere, farei quello che in Toscana vien chiamato "giropesca". Poi
magari Leonardo ci dice se c'è una strada più elegante, e perché no,
anche più breve.
$line1=preg_replace('/ +/',' ',$line1); 
// i 2 o più spazi diventano 1 su tutta la riga
$convenzionalmenteTreSpazi="   ";
$line1=preg_replace('/" /','"' . $convenzionalmenteTreSpazi,$line1); 
// lo spazio che davanti a sé ha un apice si trasforma in 3 spazi
$ar=preg_split("/$convenzionalmenteTreSpazi/",$line1);
 
print_r($ar);
-- 
mailto: y = i
----------------------------------------
Vivo nel terrore di non essere frainteso 
(Oscar Wilde)


ho provato è purtroppo non va
credo che il problema sia nel fatto che tu dai per scontato che il testo 
dentro
(innestato) sita "a" e non magari " testo "
aggiungo:
tramite regexp preg etc non è possibile definire un livello di annidamento? 
se era possibile gli dicevo livello
di annidamento 0 o 1 il minimo cmq ed il gioco era fatto


 tramite regexp preg etc non è possibile definire un livello di annidamento?
Boh :-) Direi di no, o quantomeno non riesco a pensarlo come "livello"
di annidamento". Ma è meglio ti risponda chi ne sa più di me.
Al di là di questo, perché non provi a pensare a come può essere
strutturato il pattern che ti serve? Intendo in italiano, non col
linguaggio informatico. Per capirci (la butto lì a caso): "se ho un
doppio apice che non è preceduto da uno spazio e ha davanti a sé
un'intera parola o più parole, le quali sono separate da... eccetera
eccetera". Se riesci a far questo la Regexp si trova, ci si ingegna.


Si ci sono arrivato pure però non riesco a trovare come farlo
Scusami tu: non m'ero accorto che volevi anche gli apici, e dentro ci
potevano essere altri spazi.
Stando cosi' le cose innanzitutto bisogna che tu elimini - in qualche
modo - le stringhe quotate fra apici.
Un sistema orribile e' questo, ma ne conosco di ancora peggiori :-)
<?php
$apiciato       = array();
$counter        = 0;
// Elimina tutti i dati fra apici e li salva esternamente
function apicia($testo)
{
        GLOBAL $apiciato, $counter;
        $counter++;
        $apiciato[$counter] = $testo;
        return "<<<$counter>>>";
}
function deapicia($oggetto)
{
        GLOBAL $apiciato;
        return preg_replace('/<<<([0-9]+)>>>/e',
                '"\"$apiciato[\\1]\""', $oggetto);
        // usa '"$apiciato[\\1]"' per eliminare anche i
        // doppi apici
}
$stringa        = <<<LINEA
"123456 " ciccio    "abcdefeerej" "ancora altro" drilli
LINEA;
// 1. Elimina il quotato
$stringa_senza_quotato  = preg_replace('/"([^"]*)"/e', 'apicia(\'\\1\')',
$stringa);
$campi  = preg_split('/\\s+/', $stringa_senza_quotato);
$campi  = deapicia($campi);
print "<pre>"; print_r($campi);
?>
Questo, attenzione, non ti risolve il caso AMBIGUO in cui tu abbia
	"abcdefgh "7" pippo"
perche' non si puo' decidere se questa e'
	'abcdefgh ' + '7' + ' pippo'
oppure  'abcdefgh "7" pippo'
...puoi provare a fare una serie di giri di de-quoting SUPPONENDO che la
sequenza critica sia sempre adiacente a uno spazio. Non oso pensare cosa
succeda nei casi indecidibili; probabilmente ti riformatta il server.
$stringa        = <<<LINEA
"123456 "7"" ciccio    "abcdefeerej" "ancora altro" drilli
LINEA;
//     ^^^^^ Nota che qui ho aggiunto il tuo "7", pero' e' adiacente 
// "$nyarlatothep" sarebbe piu' adatto
$cthulhu =
'/"(\\b[^"]*\\b|\\s*<<<[^"]+|[^"]+>>>\\s*|\\s*<<<[^"]+>>>\\s*)"/e';
// 1. Rimpiazzo iterativamente - qui ci starebbe bene "La Lallera" come
//    colonna sonora :-(
for ($depth = 0, $s2 = $stringa; !($depth && ($s2 == $stringa)); $depth++)
        $s2 = preg_replace($cthulhu, 'apicia(\'\\1\')', $stringa = $s2);
$campi  = preg_split('/\\s+/', $s2);
// L'unica cosa meno efficiente dell'"iterare il dequoting" e' forse
// solo "esportare democrazia". Ma mi sa che siamo testa a testa.
while(--$depth)
        $campi  = deapicia($campi);
print "<pre>"; print_r($campi);	
