ugrás a tartalomhoz

Reguláris kifejezés segítség

Meredith · 2013. Jan. 15. (K), 02.53
Sziasztok!

Már vagy 2 órát senyvedek, de nem tudtam készíteni egy megfelelő reguláris kifejezést az alábbi problémára:

Adott egy hasonló felépítésű string:
[code id="4" data="120,12,36,135,2036" extra="0"]
Ebből szeretném kinyerni egy tömbbe a data-hoz rendelt számokat.
Ameddig sikert értem el, az a számok kinyerése a strinből, így:
preg_match_all('~[0-9]+~', $code, $result);
Persze ez tartalmazza a 4-et és a 0-át is, ami nem kellene...

Tudna ebben valaki segíteni összehozni?:)


És ha már itt tartunk:
Nekem valahogy nem áll rá az agyam a regexp minták megértésére. Egy jó tutoralt is tudna valaki linkelni? Amolyan jó sok példásat, egyszerűtől a bonyolultig.

Előre is köszönöm a segítséget!
 
1

Konkrétan erre a sorra talán

eddig bírtam szó nélkül · 2013. Jan. 15. (K), 03.33
Konkrétan erre a sorra talán ez is jó:
print_r (preg_split('/^.*data="([^"]*)".*$/',$data,NULL,PREG_SPLIT_DELIM_CAPTURE));
A visszaadott tömb 1-es indexű eleme fogja tartalmazni a számokat, vesszővel elválasztva. Ebből már egyszerű "kirobbantani" a számokat. (explode, ha jól emlékszem)
De lehet, hogy van rá kulturált módszer is, ez ugyanis amellett, hogy ronda, még hibára is futhat, ha az idézőjelek közé szemét kerül.
2

Mintaillesztő kifejezés értelmesebb mint a regexp

pp · 2013. Jan. 15. (K), 09.00
A regexp arról szól, hogy illeszkedő mintákat keresünk.

pl. egy (egész)szám: legalább egy számjegyből álló, számokat tartalmazó szöveg.
[0-9]+
vesszővel elválasztott számsor: Ez nehéz, mert nincs ilyen mintánk. :) Az könnyű lenne, hogy egy szám és egy vessző legalább egyszer ismételve
(szám,)+
(([0-9]+),)+
de itt ugye mindig kell lennie vesszőnek a végén. Azonban, ha hozzáadunk még egy számot akkor kész is vagyunk:
(szám,)+(szám)
(([0-9]+),)+([0-9]+)
Na de mi van, ha nem csak számsort, hanem egyetlen egy számot is el akarunk fogadni? Egyszerű engedjük meg, hogy nulla darab előfordulása legyen a szám és vessző együttesnek.
(szám,)*(szám)
(([0-9]+),)*([0-9]+)
Na most nekünk nem az összes számsorra van szükségünk, hanem csak a data-nál lévőre.
data="(számsor)"
data="((([0-9]+),)*([0-9]+))"
könnyű dolgunk volt, mert a számsor nem tartalmazhat " jelet. Ha azt is tartalmazhatna, akkor vakarhatnánk a fejünket.

Már elég közel járunk, de nekünk olyan data-számsor kell ami a szögletes zárójelek között van.

(nyitó szögletes zárójel)(nem (záró szögletes zárójel))*(data-számsor)(nem (záró szögletes zárójel))*(záró szögletes zárójel)

nyitó szögletes zárójel: \[ (mivel [ foglalt)
nem (záró szögletes zárójel) - bármi csak az nem:[^\]]
\[([^\]])*(data="((([0-9]+),)*([0-9]+))")([^\]])*\]
kis program:
<?php
if (preg_match_all('/[0-9]+/', '[code id="4" data="120,12,36,135,2036" extra="0"]', $match)) {
    print_r($match);
}
if (preg_match_all('/(([0-9]+),)*([0-9]+)/', '[code id="4" data="120,12,36,135,2036" extra="0"]', $match)) {
    print_r($match);
}
if (preg_match_all('/data="((([0-9]+),)*([0-9]+))"/', '[code id="4" data="120,12,36,135,2036" extra="0"]', $match)) {
    print_r($match);
}
if (preg_match_all('/\\[([^\\]])*(data="((([0-9]+),)*([0-9]+))")([^\\]])*\\]/', '[code id="4" data="120,12,36,135,2036" extra="0"]', $match)) {
    print_r($match);
}
?>
A php kézikönyvben egyébként sok példát találni, érdemes azt olvasgatni.

pp
(aki ennek a feladatnak biztos nem mintaillesztő kifejezésekkel látna neki, hanem egy sima állapotmasinával)
3

Tudnád pár szóban vázolni az

eddig bírtam szó nélkül · 2013. Jan. 15. (K), 14.18
Tudnád pár szóban vázolni az "állapotmasinát"?
Úgy értem, hogy egy ilyen esetben hogyan használnád?
Karakterről, karakterre elemeznéd a feldolgozandó sort? Vagy hogy gondolod?
6

Köszi!

Meredith · 2013. Jan. 15. (K), 15.11
Köszi a kimerítő választ!
Így már remekül működik a dolog! :)
7

aki ennek a feladatnak biztos

Joó Ádám · 2013. Jan. 15. (K), 16.53
aki ennek a feladatnak biztos nem mintaillesztő kifejezésekkel látna neki, hanem egy sima állapotmasinával


+1
8

Nem tudom neked ez a [0-9]

inf · 2013. Jan. 17. (Cs), 15.18
Nem tudom ez a [0-9] honnan jött:
data="(\d+(?:,\d+)*)"
Attól függően, hogy mekkora rugalmasságra van szükség, lehet, hogy az xml-es megoldás - amit lentebb írtak - jobb.
9

- Talán a témaindító

pp · 2013. Jan. 17. (Cs), 22.00
- Talán a témaindító hozzászólásból, Sherlock. - révedt a távolba Dr. Wattson elgondolkodva.
10

És télleg. :-)

inf · 2013. Jan. 18. (P), 04.03
És télleg. :-)
4

SimpleXMLElement

T.G · 2013. Jan. 15. (K), 14.42

<?php
$str = '[code id="4" data="120,12,36,135,2036" extra="0"]';
$xmlStr = '<' . substr($str, 1, -1) . ' />';
$xml = new SimpleXMLElement($xmlStr);
echo $xml{'data'};
Nem a legoptimálisabb megoldás, de érdekességképpen ide illik. :)
5

Mondjuk elsőre én valami

eddig bírtam szó nélkül · 2013. Jan. 15. (K), 14.46
Mondjuk elsőre én valami BBCode parserben gondolkodtam volna, de lusta voltam utánajárni, hogy megoldható-e. :-)