Autor | Zpráva | ||
---|---|---|---|
Majkelju Profil |
Zdravím! Mám sestavený regulární výraz pro vybrání textu mezi všemi tagy <t></t> :
preg_match_all('/<t>(.*?)<\/t>/s', $text, $match); ... Jak ale udělat, aby mi to ten text vybralo jen v případě, že má alespoň 3 znaky?
|
||
Str4wberry Profil |
#2 · Zasláno: 5. 12. 2012, 09:30:22
Stačí použít příslušný kvantifikátor. Tedy
{3,} . Hvězdička znamená libovolný počet a otazník ani jednou až maximálně jednou.
|
||
juriad Profil |
#3 · Zasláno: 5. 12. 2012, 10:03:33
aby byl regex nežravý, musíš zachovat i otazník:
#<t>(.{3,}?)</t>#
a můžeš použít i jiný znak (třeba mřížku) než lomítko pro ohraničení: vyhneš se tak jeho escapování |
||
Majkelju Profil |
#4 · Zasláno: 5. 12. 2012, 10:06:23
Ok, děkuji, takhle to funguje, jediný problém je, když je v tagu <t> m2</t>, tak to vybere taky, protože tu mezeru to vlastně počítá taky...nedá se tam přidat něco jako trim() ?
|
||
Joker Profil |
Majkelju:
trim by šel simulovat, když použiji juriadovo řešení: #<t>(\s*)([\S]{3,}?)(\s*)</t># Oprava, i za druhým (\s) měla být hvězdička oprava 2, přehnal jsem to s negacemi, \S je všechno kromě bílých znaků, takže už není třeba negovat. |
||
juriad Profil |
#6 · Zasláno: 5. 12. 2012, 10:13:47 · Upravil/a: juriad
#<t>\s*(.{3,}?)\s*</t># \s: Match a whitespace character tedy mezery, tabulátory a podobnou havěť bude přeskakovat Joker: nedávej whitespacy do závorek, zbytečně plýtváš referencí, kterou nikdy nepoužíješ na konci, u druhého \s ti chybí hvězdička uprostřed není třída [^\S], takto jsi definoval, že střed má obsahovat alespoň tři whitespacy, dokonce tam nemůže být ani [^\s] by pak střed nesměl obsahovat ani mezeru, například: <t> čtyři slova oddělená mezerami </t>
protože střed je stejně nežravý, takže tam nemusí žádná třída být, protože whitespacy stejně končit nebude |
||
Joker Profil |
[#6] juriad:
Bude to takhle fungovat? Podle mě třeba <t> x </t> tomu reguláru vyhoví, protože \s* vyhoví i prázdný řetězec a to x s mezerami vyhoví té vnitřní závorce.
Ale napadá mě, že s tím mým výrazem zas nebudou fungovat ani mezery uvnitř toho textu. dotatek, zmíněnou hvězdičku a ^\S jsem mezitím už opravil. |
||
Majkelju Profil |
Tak nevím, co tam mám za kiks, ale Jokerovo řešení mi nevybírá nic a juriadovo mi naopak vybere kromě textu i nějaké další tagy navíc...
Původní text vypadá takto: <vv><r><t>plocha NK: </t><v>50*11</v><vy>A</vy><t> m2</t></r><r><v /><t>tloušťka NK: </t><v>0,75</v><vy>B</vy><t> m</t></r><r><t>kubatura: </t><v>a*b</v><vy>C</vy><t> m3</t></r></vv> Jokerovo řešení: 50*11 = 550 0.75 = 0.75 a*b = 0 juriadovo řešení: plocha NK:50*11 = 550 m2</t></r><r><v ></v><t>tloušťka NK:0.75 = 0.75 m</t></r><r><t>kubatura:a*b = 0 Vypadat by to mělo jako: plocha NK:50*11 = 550 tloušťka NK:0.75 = 0.75 kubatura:a*b = 0 DODATEK: Jde tu vlastně jen o ty nápisy, regex na výběr čísel mi funguje a neuvádím ho tu... |
||
Joker Profil |
#9 · Zasláno: 5. 12. 2012, 10:51:27
Majkelju:
No, další komplikace je, že: <t>x</t> -něco dalšího-<t>y</t> Jinak řešeno, když v nějaké značce <t> budou méně než tři znaky, pořád tomu výrazu může vyhovovat když se vezme i koncová značka a ještě další obsah až po koncovou značku příštího <t>. Navíc mám dojem, že ta podmínka ve skutečnosti nemá být značka <t> s více než třemi znaky uvnitř, ale první značka <t> uvnitř značky <r>. Kdyby třeba kubatura byla v cm3, zase to nebude fungovat. Obecně by se pro zpracování XML měl používat XML parser a regulární výrazy jen pro opravdu triviální situace. |
||
Jan Tvrdík Profil |
#10 · Zasláno: 5. 12. 2012, 10:52:46
Majkelju:
Proč nepoužiješ XMLParser? Např. SimpleXml. |
||
Majkelju Profil |
O XMLParseru jsem ještě neslyšel...to se musí nějak nainstalovat? Nebo ta podmínka by se nedala nějak rozumně upravit?
EDIT: Joker: Ano, taková podmínka by byla asi jednodušší... To se taky dá pomocí regexu? Omlouvám se, že jsem úplně mimo, ale ani po projití značek, které může výraz obsahovat, z toho nejsem moc moudrý... Ještě mě napadlo, že by možná šlo umazat ten nechtěný kus textu (abych to nemusel celé předělávat na ten parser)...to myslím nějak jde, ne? Aby to smazalo vše od začátku až po uzavírací zobáček tagu <t>. Je to asi prasárna, ale jde v podstatě jen o obyčejný výpis textu, tak s tím nechci strávit půl dne... |
||
Jan Tvrdík Profil |
Majkelju:
„O XMLParseru jsem ještě neslyšel...to se musí nějak nainstalovat?“ Pokud nemáš speciálně zkompilované PHP, tak tam SimpleXML budeš mít k dispozici. Česky jsem o SimpleXML našel • programovani.blog.zive.cz/2009/12/simplexml-jednoduse-na-xml-v-php-1dil • programovani.blog.zive.cz/2009/12/simplexml-jednoduse-na-xml-v-php-2dil • www.devbook.cz/php-cteni-xml-tridou-simplexml Třeba takto nějak: <?php $s = '<vv> <r> <t>plocha NK: </t> <v>50*11</v> <vy>A</vy> <t> m2</t> </r> <r> <v /> <t>tloušťka NK: </t> <v>0,75</v> <vy>B</vy> <t> m</t> </r> <r> <t>kubatura: </t> <v>a*b</v> <vy>C</vy> <t> m3</t> </r> </vv>'; $xml = simplexml_load_string($s); foreach ($xml->r as $r) { foreach ($r->v as $v) { $v = trim($v); if (empty($v)) continue; echo "V: $v<br>\n"; } foreach ($r->t as $t) { echo "T: $t<br>\n"; } } |
||
Majkelju Profil |
#13 · Zasláno: 5. 12. 2012, 11:56:14
Jan Tvrdík:
Aha, díky :) Jinak momentálně jsem to metodou pokus-omyl vyřešil pomocí echo preg_replace('#.*?<t>#', "", $pole[$i]); |
||
peta Profil |
Treba takovyto priklad ti pomuze s xm parserem a prestanes resit reg vyrazy.
http://peter-mlich.wz.cz/web/php/pr/wheather-wunderground.php http://peter-mlich.wz.cz/web/php/pr/wheather-wunderground.txt preg_match_all('/<t>(.*?)<\/t>/s', $text, $match); #<t>(\s*)([\S]{3,}?)(\s*)</t># - kdyz tam nechas ty zavorky, tak match vybira zavorku po zavorce 1, 2 i 3 a jestli jsi tam nechal $match[1], tak je jasne, ze ti to nejde. Takze bych ty zavorky zrusil
#<t>\s*([\S]{3,}?)\s*</t># |
||
Časová prodleva: 11 let
|
0