Portál AbcLinuxu, 18. dubna 2024 03:19


Dotaz: Python - regulární výraz

7.1.2008 15:32 Bobo
Python - regulární výraz
Přečteno: 1926×
Odpovědět | Admin

Zdravím,
potřeboval bych poradit s regulárním výrazem v Pythonu (mám verzi 2.5), který by podle mne měl být velmi snadný, přesto se mi však stále nedaří, aby fungoval tak, jak chci.

Konkrétně potřebuji, abych v řetězci našel takovou sekvenci znaků, která najde v řetěci číslo, ovšem s podmínkou, že před číslem nesmí být sekvence znaků "log" a za číslem nesmí být znak ".".

Pro lepší pochopení problému to bude sloužit k nahrazení nalezeného čísla za číslo ve tvaru float, teda za nalezené číslo přidám ".0". Výjimky jsou zřejmé: nechci nahradit "log10" za "log10.0" a nechci nahradit číslo, které již ve tvaru float je. Nahrazování hodím do cyklu a tím se postupně nahradí všechna int čísla.

Já bych to úplně chápal takto, ovšem Python ne :)

import re
str = 'retezec 246 obsahujici 4564 cisla a vyjimky: log10 5.2'
p = re.compile("^(log)([0-9]+)(^.)")
print re.match(p, str)
n=re.match(p, str)
if n: print n.group(1)

Mimochodem je jasné, že v tomto pokusném zdrojáku nemám cyklus, a proto dojde jen k nalezení první odpovídající sekvence znaků.

Mnohokrát děkuji za pomoc.

Nástroje: Začni sledovat (1) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

7.1.2008 16:16 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Python - regulární výraz
Odpovědět | | Sbalit | Link | Blokovat | Admin
(?<=log)[0-9]+(?=\.)
7.1.2008 16:23 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Python - regulární výraz
oprava ... miesto = v oboch prípadoch použiť !
7.1.2008 17:59 Bobo
Rozbalit Rozbalit vše Re: Python - regulární výraz

Moc díky, funguje to zatím nejlíp ze všech mých pokusů... :) Ale narazil jsem na tři problémy, popsané v komentářích. Jsem fakt amatér v regulárních výrazech (ale než jsem se zde zeptal, studoval jsem samozřejmě manuál, ale např. to "?<=" jsem v něm vůbec nenašel), tak nevím, jestli to jimi vůbec jde (ty tři problémy), nebo si s tím budu muset pohrát pomocí podmínek. Díky moc, věřím, že zkušeným to zabere jen pár vteřin...
(mimochodem, už chápu, proč jsi napsal = místo !, já taky musel...)

import re str = 'nejake znaky 6.0 '
p = re.compile("(?<=log)([0-9]+)(?=\.)")
print re.search(p, str)
n=re.search(p, str)
if n: print n.group(1)

#pokud je tam 246.0 najde 24, pokud je tam napr. log123, najde 23, potreboval bych, aby ignoroval cele cislo
#jeste problem: najde cislo/cisla za znakem "."

7.1.2008 20:33 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Python - regulární výraz
ad log123 ... pomôže pridaná podmienka nečíslo alebo hranica slova ... (?<!log)((?<=\D)|\b)(\d+) (dúfam, že to python pozná, používam perl)
druhú stranu bude treba ošetriť podobne.
problém "číslo za bodkou" by sa dal riešiť vložením (?<!\.)
7.1.2008 20:38 happy barney | skóre: 34 | blog: dont_worry_be_happy
Rozbalit Rozbalit vše Re: Python - regulární výraz
finálna verzia: (?<!log)(?<!\d)(?<!\d\.)(\d+) (dnes už naposledy)
8.1.2008 22:41 bobo.rimis
Rozbalit Rozbalit vše Re: Python - regulární výraz

Ještě pořád to dělá 2 věci, které si nepřeji:
pokud je tam 12.345, najde 1
pokud je tam 1.2345, nejde 2345

Jinak mnohokrát děkuji, na tyto dvě chyby bych už možná přišel sám, ale kdyby ne, tak by už tento dotaz nebyl aktuální a byl by považován za vyřešený (což jsem zrušil). Děkuji za pochopení ;)

8.1.2008 22:43 bobo.rimis
Rozbalit Rozbalit vše Re: Python - regulární výraz

A já bych potřeboval, aby to v těchto případech nenašlo nic. (pro jistotu doplňuji...)

9.1.2008 01:38 Dunric | skóre: 21
Rozbalit Rozbalit vše Re: Python - regulární výraz
Odpovědět | | Sbalit | Link | Blokovat | Admin
str = 'retezec 246 obsahujici 4564 cisla a vyjimky: log10 5.2'	# cokoliv
p = re.compile('(?<!log)(?<!\.)(?<!\d)\d+(?!\d)(?!\.)')	  # osetrit vsechny pripady
n = p.findall(str)
if n:
	for fixn in n:
		…
Dále viz re.sub .
In the garden sleeps a messenger ·
9.1.2008 16:42 bobo.rimis
Rozbalit Rozbalit vše Re: Python - regulární výraz

Mnohokrát Ti děkuji! Fakt jo, vyřešil jsi můj problém, se kterým už jsem se vážně dlouho trápil a nikdo mi nedokázal pomoci. Funguje to přesně tak, jak jsem chtěl. Jen bych byl ještě moc vděčný za slovní popis toho regulárního výrazu, abych to dokonale pochopil a příště se nemusel ptát... ;)

Jinak tady je ten prográmek, kvůli kterému jsem to potřeboval:

retez=raw_input("Zadej retezec: ")
import re
import string
reg = re.compile("(?<!log)(?<!\.)(?<!\d)(\d+)(?!\d)(?!\.)")
while reg.search(retez):
x = reg.search(retez)
nalez = str(x.group(1))
novy=nalez+".0"
retez=string.replace(retez, nalez, novy, 1)
print retez

Ještě jednou díky :)

9.1.2008 19:46 Dunric | skóre: 21
Rozbalit Rozbalit vše Re: Python - regulární výraz
Myslím že je to jasné přímo z oficiální dokumentace .

Ve zkratce jde o to, že ta sekvence čísel nejen nesmí následovat za "log" a předcházet tečce, ale zároveň nesmí předcházet a následovat jakékoliv číslici a i následovat tečce, jinak dostaneš fragmenty, které zjevně odpovídají té úvodní podmínce.

In the garden sleeps a messenger ·
9.1.2008 19:47 Dunric | skóre: 21
Rozbalit Rozbalit vše Re: Python - regulární výraz
s/odpovídají/vyhovují/
In the garden sleeps a messenger ·

Založit nové vláknoNahoru

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

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