Portál AbcLinuxu, 25. října 2026 19:01


Dotaz: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu

16.3.2007 01:43 madA | skóre: 12 | blog: fallout | electronic frontier
Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Přečteno: 387×
Odpovědět | Admin
Zdravim,
mam nejaky xml retezec ve kterem je X tagu <NewsItem></NewsItem> mym cilem je ulozit kazdy par i s jeho obsahem do jine promene/souboru...

takze:
while ($xmlretezec =~ /(<NewsItem>[\s\S]+<\/NewsItem>)/g) {
$counter++;
$pole[$counter] = $1;
};


problem:
cyklus probehne pouze jednou a do promene se ulozi <NewsItem>....</NewsItem><NewsItem>+++++</NewsItem>

nejak nejsem schopen pochopit (doguglit, docist z tech par ucebnic co k perlu mam), kde je error...

perl by se podle me mel zastavit na prvnim vyskytu </NewsItem> nechat probehnout cyklus a pak pokracovat, kde skoncil - tj za prvnim vyskytem </NewsItem> a to opakovat az do konce souboru...

Predem diky za jakkoukoliv reakci, je mi jasny ze zrejme nechapu jak to funguje :-/
war is peace freedom is slavery ignorance is strenght Zabij komunistu, posílíš mír.
Nástroje: Začni sledovat (4) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

16.3.2007 03:54 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Podle mě není moc rozumné prohánět xml soubor přes regulární výrazy, protože to nikdy nebude fungovat pořádně. Použij existující xml parser. Jsem si jist, že v perlu jich je spousta, ale udělat bych to uměl asi jen v pythonu. Kdyby měl soubor.xml třeba tento obsah
<xml>
    <NewsItem>prvni</NewsItem>
    <NewsItem>druhy</NewsItem>
    <NewsItem>treti</NewsItem>
</xml>    
pak by se dal parsovat třeba tímto
#!/usr/bin/env python
from elementtree.ElementTree import *
root = ElementTree(file='soubor.xml')
for news in root.getroot():
    print news.text
a výsledek by byl
prvni
druhy
treti
Kdybys podrobněji popsal strukturu tvého xml souboru, dalo by se to napsat přímo na míru.
16.3.2007 06:56 Tomáš Janeček | skóre: 12
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Problém je, je pomocí g v regulárním výrazu říkáš, aby regulární výraz našel všechno najednou. Proto to nepoběží vícekrát. Když tam to g nedáš, bude se to naopak točit do nekonečna...

Já bych to asi dělal takhle:
while($xmlretezec =~ s#(<NewsItem>[\s\S]+</NewsItem>)##)
{
     $counter++;
     $pole[$counter] = $1;
}
nebo pokud se zbavím citové vazby na cyklus while ;-) takhle:
for($counter=0;$xmlretezec =~ s#<NewsItem>[\s\S]+</NewsItem>##;$counter++)
{
     $pole[$counter] = $1;
}
což je mnohem lepší řešení, protože má o jeden řádek méně :))) (vtip)
Něco děsně chytrýho a vtipnýho
16.3.2007 08:28 ph0enix | skóre: 18 | Praha
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu

Musim vas zklamat, ale nemate pravdu. Problem je v defaultni zravosti regexpu. Pokud tuto neomezite, coz jste neudelal, tak kod fungovat nebude. Navic jste v prikladu s cyklem for opomenul rici PERLu aby si nalezenou shodu zapamatoval. Nasledujici kod by uz mel fungovat, ma vsak jednu vlastnost ktera vy se nemusela byt zcela zadouci a to, ze modifikuje puvodni text v promenne $xmlretezec - vsechny nalezene shody proste z puvodniho textu vyrizne...

for($counter=0;$xmlretezec =~ s#(<NewsItem>[\s\S]+?</NewsItem>)##;$counter++) {
  $pole[$counter] = $1;
}
16.3.2007 08:07 ph0enix | skóre: 18 | Praha
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin

Problem tkvi v tom, ze regularni vyrazy v PERL jsou zrave a snazi se najit co nejdelsi shodu, takze pro takto zadany regexp vezmou prvni znacku <NewsItem> a pak vsechno az po posledni znacku </NewsItem> kterou v promenne $xmlretezec najde. Staci omezit tuto defaultni zravost perlu pridanim '?' za '+' a kod se bude chovat tak jak ocekavate.

while ($xmlretezec =~ /(<NewsItem>[\s\S]+?<\/NewsItem>)/g) {
  $counter++;
  $pole[$counter] = $1;
}
16.3.2007 12:03 ph0enix | skóre: 18 | Praha
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu

A pokud to ma jen prijit na konec nejakeho pole, tak to jde i takto

push @pole, $xmlretezec =~ /(<NewsItem>[\s\S]+?<\/NewsItem>)/g;
16.3.2007 09:32 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin
špeciálny znak:
\G Match only where previous m//g left off (works only with /g)

modifikátor:
s Treat string as single line. That is, change ``.'' to match any character whatsoever, even a newline, which it normally would not match.

výsledok:

while ($xmlretezec =~ /\G.*?(<NewsItem>.+?<\/NewsItem>)/gs) {
    push @pole, $1;
};
16.3.2007 13:01 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
V tomto případě je \G zbytečné, stejně tak dobře poslouží
while ($xmlretezec =~ /(<NewsItem>.+?<\/NewsItem>)/gs) {
    push @pole, $1;
};
Viz:
 $ perl -le '$/=undef;$a=<>;while($a=~/(<NewsItem>.+?<\/NewsItem>)/gs){print $1}' <<EOF
<xml>
    <NewsItem>pr
vni</NewsItem>
    <NewsItem>druhy</NewsItem>
<NewsItem>tr
et
i</NewsItem>
</xml>
EOF
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
16.3.2007 13:56 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
hmm, tak to mi asi niečo ušlo ...
chybka je tam však stále :-)
while ($xmlretezec =~ /(<NewsItem>(.+?)<\/NewsItem>)/gs) {
    push @pole, $1 if $2;
};
16.3.2007 15:34 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Proč?
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
16.3.2007 15:39 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
aha, pardon, ja som to nezmenil :-)
malo tam byť .*?, keď element obsahuje text s dĺžkou 0.
16.3.2007 13:46 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Když už se to tady hemží různými řešeními, přidám ještě jedno další.
python << EOF
from elementtree.ElementTree import *

xml = '''
  <xml>
    <NewsItem attr='bleble'>prvni</NewsItem>
    <NewsItem >dr
    uhy<tento_tag_nechci>ignoruj</tento_tag_nechci></NewsItem>
    <NewsItem>treti</NewsItem>
  </xml>
'''

elem = fromstring(xml)
pole = [news.text for news in elem.getiterator('NewsItem')]
print pole

EOF
Uvádím výsledek pro ty, kterým je proti srsti vzít do myši úplně cizí kód a strčit si ho do terminálu :-)
['prvni', 'dr\n    uhy', 'treti']
16.3.2007 13:58 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
správny výstup by mal byť:
['prvni', 'dr\n    <tento_tag_nechci>ignoruj</tento_tag_nechci>uhy', 'treti']
keď už :-)
16.3.2007 15:32 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
To asi bylo myšleno jako vtip, že? :-)
Když budu chtít procházet všechny tagy a jejich texty, tak to udělám takto
python << EOF
from elementtree.ElementTree import *
import re

xml = '''
  <xml>
    <NewsItem attr='bleble'>prvni</NewsItem>
    <NewsItem >dr
    uhy<tento_tag_nechci>ignoruj</tento_tag_nechci></NewsItem>
    <NewsItem>treti</NewsItem>
  </xml>
'''

elem = fromstring(xml)
for e in elem.getiterator():
    print (e.tag, e.text)
EOF
Výsledek:
('xml', '\n    ')
('NewsItem', 'prvni')
('NewsItem', 'dr\n    uhy')
('tento_tag_nechci', 'ignoruj')
('NewsItem', 'treti')
16.3.2007 15:41 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
A sémantickou informaci, že ('tento_tag_nechci', 'ignoruj') je součástí tagu ('NewsItem', 'dr\n uhy') a nachazi se za 'dr\n uhy' se vám ztratila kde? Třeba ji autor dotazu nehodlal ztratit. Teda krom toho, že se ptal na implementaci v perlu což výslovně uvedl v přímo v titulku dotazu.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
16.3.2007 15:53 Pavel1 | skóre: 33
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
že se ptal na implementaci v perlu což výslovně uvedl v přímo v titulku dotazu.
To že J.M. neustále u všech hledaných řešení doplňuje i o svoje řešení v Pythonu, to vidím jako plus a vůbec bych ho od toho neodrazoval. Jestli dotazující řešení v Pythonu nepoužije, nevadí (může to mlčky přehlédnout). Ale pro ostatní "přihlížející" návštěvníky to může být zajímavá ukázka a alternativa, jak to lze řešit i jinak. Takže jen tak dál, i když je požadavek třeba na Perl, proč si neprohlédnout i jiná řešení ...
16.3.2007 16:25 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Děkuji, náčelníku, že ses mě zastal! :-)
16.3.2007 17:19 Pavel1 | skóre: 33
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
To, že jsem se Tě zastal, to bylo vyloženě "sobecké" :-) :-) . Protože kdybych někdy potřeboval a chtěl proniknout do tajů Pythonu, Tvé příspěvky mi budou sloužit jako praktické ukázky. :-)
16.3.2007 17:29 Hynek (Pichi) Vychodil | skóre: 43 | blog: Pichi | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Domnívám se, že k pronikání do tajů pythonu jsou mnohem vhodnější materiály.
XML je zbytečný, pomalý, nešikovný balast, znovu vynalézané kolo a ještě ke všemu šišaté, těžké a kýčovitě pomalované.
16.3.2007 16:23 Jan Martinek | skóre: 43 | blog: johny | Brno
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Se vším samozřejmě souhlasím. Tu informaci z xml jsem ale zahodil schválně, jelikož jsem si zadání do značné míry vykonstruoval. Vůbec nevím, k čemu přesně to má sloužit. Třeba se ještě autor dotazu ozve.
16.3.2007 15:46 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
to nebolo myslené ako vtip, to bol fakt. Váš výsledok napr neakceptuje:
<NewsItem><b>Category:</b> <i>title</i></NewsItem>
a podobne, ako príklad to snáď postačuje
16.3.2007 20:23 madA | skóre: 12 | blog: fallout | electronic frontier
Rozbalit Rozbalit vše Re: Perl problem s tvorbou regexpu pro opakovane vyhledavi vyrazu
Odpovědět | | Sbalit | Link | Blokovat | Admin
Diky moc za rady, tolik jsem jich ani necekal :-D

Jedna se o skript do cronu, ktery ma stahnout httpkem xml soubor s novinkami (obsazenymi v tagu newsitem) od posledniho stazeni. A ulozit kazdou novinku jako samostatny xml soubor pod datem jejiho vydani. Nejake cms si z nich pote nacita data.

Nejsem programator, takze jsem si zjednodussil praci wgetem ls apod.

war is peace freedom is slavery ignorance is strenght Zabij komunistu, posílíš mír.

Založit nové vlákno • Nahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.