Newsgroup: it.comp.www.php
Titolo: espressione in preg_match

Ciao a tutti, purtroppo non ho molta conoscenza delle regexp e quindi
vi sottopongo una (spero) semplice domanda:
$str = "<pippo>1 2 3</pippo><pippo>4 5 6</pippo>";
preg_match_all( "/<pippo>(.*)</pippo>/", $str, $match );
contrariamente a quanto mi sarei aspettato, quel (.*) matcha anche </
pippo> se poi ce ne è un altro dopo, quando invece io vorrei ottenere
due match, uno con 1 2 3 e uno con 4 5 6. Sapreste indicarmi il modo ?
Ovviamente al posto di 1 2 3 ci puo essere uno qualunque dei caratteri
presenti nella stringa "</pippo>" (ma non tutti insieme) quindi
soluzioni tipo
"/<pippo>([^<]*)</pippo>/" non funzionerebbero.
Visto che ci sono ho un'altra domanda: c'è modo di eseguire preg_match
in modalità multiline ? ora come ora devo rimpiazzare tutti i "\n" e
"\r" di $str con caratteri vuoti altrimenti non mi funziona alcun
match su piu linee.
Grazie
Matic

 match su piu linee.
Guarda tra i modificatori.
http://it.php.net/manual/en/reference.pcre.pattern.modifiers.php
Ciao
Maverick
-- 
«Che non siete più liberi di non avere una casa con letto per dormire.
 Lavorate voi - schiavi dei soldi - che non sentite la puzza della
 schiavitù!» (a Mario di Monte Mario, Roma) # 
http://libre.netsons.org/

 Maverick
hai vinto per 24 secondi... a quando la rivincita? :-D
ciao 
DonnieDarko

 Prova con "<pippo>(.*?)</pippo>" come regex.
Ehm, ora che ci penso, devi fare l'escape di '/' ==> "...<\/pippo>".
Ciao
Maverick
-- 
«Che non siete piů liberi di non avere una casa con letto per dormire.
 Lavorate voi - schiavi dei soldi - che non sentite la puzza della
 schiavitů!» (a Mario di Monte Mario, Roma) # 
http://libre.netsons.org/

Gentilissimi
Ciao

 hai vinto per 24 secondi... a quando la rivincita? :-D
Alla prossima regex!
Ciao ;P
Maverick
-- 
ĢChe non siete pių liberi di non avere una casa con letto per dormire.
 Lavorate voi - schiavi dei soldi - che non sentite la puzza della
 schiavitų!ģ (a Mario di Monte Mario, Roma) # 
http://libre.netsons.org/

 Ehm, ora che ci penso, devi fare l'escape di '/' ==> "...<\/pippo>".
Mi metto nel thread per sollevare un altro dubbio :-)
E se invece la stringa è del tipo:
"<pippo>1 <pippo>2</pippo> 3</pippo>"
Come faccio a tirar fuori il contenuto del primo tag (o anche del 
secondo)?
Cioè non voglio che mi sia restituito ad esempio:
"1 <pippo>2" perché, pur essendo compreso tra <pippo> e </pippo>, non è 
corretto.
Così come non voglio che mi sia restituito "2</pippo> 3".
In pratica, voglio che mi sia restituito:
- "1 <pippo>2</pippo> 3" in un caso
- "2" nell'altro caso
Ah, sottolineo che ovviamente l'innestamento dei tag può pure 
complicarsi. :-)
--
rob4you

secondo)?
E' a questo che serve il punto interrogativo in quella regexp la' sopra,
detto modificatore "greedy". In un caso acchiappa tutto, e nell'altro il
meno possibile.
Leonardo
-- 
Next in importance to freedom and justice is popular education, without which neither can be permanently maintained.
James A. Garfield (1831 - 1881)

 meno possibile.
Forse sarò io che ho sbagliato a scrivere. Ma guarda questo esempio:
<?php
$str = "<pippo>1 2 3</pippo><pippo>4 <pippo>5</pippo> 6</pippo>";
preg_match_all( "/<pippo>(.*?)<\/pippo>/",$str,$matches);
print_r($matches);
?>
Se io volessi, razionalmente, trovare tutti i contenuti che ho 
internamente ai tag "pippo", vorrei qualcosa del genere:
- 1 2 3
- 4 <pippo>5</pippo> 6
- 5
E invece, cioò che ottengo è (magari vedilo con un font mono-spaced, 
salvo mal di testa :-) ):
Array
(
    [0] => Array
        (
            [0] => 1 2 3
            [1] => 4 5
        )
    [1] => Array
        (
            [0] => 1 2 3
            [1] => 4 5
        )
)
Cosa sbaglio?
--
rob4you

 complicarsi. :-)
Non so se esista una soluzione univoca valida per qualsiasi livello.
In generale, è meglio dare una "mano" alle regex con un parser. ;-)
Ad ogni modo, stabilito il livello di profondità/ricorsione che si vuole
avere, basta sostituire ".*?" con "(?:<\\1>.*?<\/\\1>|.)*?" per ogni
livello in più che si vuole ottenere.
<(pippo)>.*?<\/\\1>
<(pippo)>(?:<\\1>.*?<\/\\1>|.)*?<\/\\1>
<(pippo)>(?:<\\1>(?:<\\1>.*?<\/\\1>|.)*?<\/\\1>|.)*?<\/\\1>
e così via...
Ciao
Maverick
ps. dovresti smetterla di sollevare certi dubbi! ;P
-- 
«Che non siete più liberi di non avere una casa con letto per dormire.
 Lavorate voi - schiavi dei soldi - che non sentite la puzza della
 schiavitù!» (a Mario di Monte Mario, Roma) # 
http://libre.netsons.org/

 $re l'ho divisa solo per non superare i 72 char a linea :)
tra l'altro, bastava un livello in meno...
Ciao
Maverick


 In generale, è meglio dare una "mano" alle regex con un parser. ;-)
E' per questo che son un fervido sostenitore dei parser!! :-)
Comunque è impressionante....sia il fatto che tu abbia dato una 
risposta al mio dubbio amletico (prometto di contenermi d'ora in 
poi)....sia il livello di casino che si arriva a toccare per gestire 
situazioni complesse....quasi che sarebbe più facile dire "non si può 
fare!". :-)
Considerando poi che all'interno di un tag il nome potrebbe essere lo 
stesso, ma gli attributi variare a piacimento...ahia....già mi viene 
male agli occhi a immaginare una possibile lettura.
Già....in questo caso, o comunque nei casi generali, in cui non si 
conosce il livello di profondità, moooolto meglio le amatissime 
funzioni del dom.
--
rob4you