Fórum Ubuntu CZ/SK
Ubuntu pro osobní počítače => Software => Příkazový řádek a programování pro GNU/Linux => Téma založeno: YaD 09 Srpna 2011, 21:44:34
-
Regulárny výraz sa má používať na zachytávanie a spracovávanie takýchto vstupov:
(x^2+5y)^2
(1*x+2y)**4
a pod.
Analýza binomickej vety. Jedná sa o úpravu kódu z http://forum.ubuntu.cz/index.php/topic,57077.0.html .
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla
( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)? # nevyžadujeme ho povinne - násobenie
( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|**) # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný
) # blok je u konca
{2} # vyžadujeme ho dvakrát
\) # koniec číselného vyjadrenia
(?:^|**) # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)
print(pattern.search(input()).groups())
Neviem kde je chyba, keďže hláška pri kompilácii mi veľa nepovie, keďže do regulárnych výrazov dobre nevidím:
$ python3 expr.py
Traceback (most recent call last):
File "expr.py", line 29, in <module>
''', re.VERBOSE)
File "/usr/lib/python3.1/re.py", line 205, in compile
return _compile(pattern, flags)
File "/usr/lib/python3.1/re.py", line 273, in _compile
p = sre_compile.compile(pattern, flags)
File "/usr/lib/python3.1/sre_compile.py", line 491, in compile
p = sre_parse.parse(p, flags)
File "/usr/lib/python3.1/sre_parse.py", line 692, in parse
p = _parse_sub(source, pattern, 0)
File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
p = _parse_sub(source, state)
File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
p = _parse_sub(source, state)
File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/lib/python3.1/sre_parse.py", line 640, in _parse
p = _parse_sub(source, state)
File "/usr/lib/python3.1/sre_parse.py", line 315, in _parse_sub
itemsappend(_parse(source, state))
File "/usr/lib/python3.1/sre_parse.py", line 520, in _parse
raise error("nothing to repeat")
sre_constants.error: nothing to repeat
Ďakujem za akúkoľvek pomoc.
-
btw je to tim ze nemas escapovany * - coz je meta znak, opravil sem ti to, jen to nic nenajde, takze mas ten regular spatne
(django13)starenka@kosmik1:/junk$ python meh.py
(1*x+2y)**4
(1*x+2y)**4
Traceback (most recent call last):
File "meh.py", line 33, in <module>
print(re.search(pattern,expr).groups())
AttributeError: 'NoneType' object has no attribute 'groups'
!/usr/bin/env python3.1
# -*- coding: utf-8 -*-
import re
pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla
( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)? # nevyžadujeme ho povinne - násobenie
( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|\*\*) # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný
) # blok je u konca
{2} # vyžadujeme ho dvakrát
\) # koniec číselného vyjadrenia
(?:^|\*\*) # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)
expr = raw_input()
print(expr)
print(re.search(pattern,expr).groups())
#print(pattern.search(expr).groups())
-
Moc díky. S tým sa už pohrám :).
-
nejlepsi je si na to napsat test, pokud si na pochybach...
-
Pravda, len s týmto sa hrám značne bokom, keďže píšem kde čo iné, takže to aj tak vyzerá.
V každom prípade K+. ;)
-
NP, fakt si to podchyt tim testem, ala (hodne z rychliku):
starenka@kosmik1:/junk$ cat meh.py
#!/usr/bin/env python3.2
# -*- coding: utf-8 -*-
import re
import unittest
pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla
( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
)? # nevyžadujeme ho povinne - násobenie
( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:^|(\*\*)) # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný
) # blok je u konca
{2} # vyžadujeme ho dvakrát
\) # koniec číselného vyjadrenia
(?:^|(\*\*)) # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)
class ReTest(unittest.TestCase):
VALID_EXPRS = ['(x^2+5y)^2','(1*x+2y)**4']
NOT_VALID_EXPRS = ['(1*x+2y)*4','(a+b)^2']
def test_ok(self):
for expr in self.VALID_EXPRS:
print(expr)
self.assertEqual(True,bool(re.search(pattern,expr)))
def test_bad(self):
for expr in self.NOT_VALID_EXPRS:
print(expr)
self.assertEqual(False,bool(re.search(pattern,expr)))
if __name__ == '__main__':
unittest.main()
starenka@kosmik1:/junk$ python meh.py
(1*x+2y)*4
(a+b)^2
.(x^2+5y)^2
F
======================================================================
FAIL: test_ok (__main__.ReTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "meh.py", line 39, in test_ok
self.assertEqual(True,bool(re.search(pattern,expr)))
AssertionError: True != False
----------------------------------------------------------------------
Ran 2 tests in 0.000s
FAILED (failures=1)
-
Pravda, unit testovanie chce svoj čas, ale teraz skôr skladám ten regulárny výraz napísať od jednoduchého k zložitému, keďže vyššie spomenuté som napísal celé v kuse.
Nič iné ako znovu díky ti nemôžem povedať :).
-
(sem to jeste potunil - cekni znova ten kod). no od toho ten test je... nahazis si co chces a co ne a pak je tunis ten regular a nemusis to rucne zkouset, cili to pomaha UZ pri tom, co to pises
-
Tak ja len v terminále ťuknem na šipku hore, keďže mám jeden vstup na súbore:
$ python3 expr.py < test.in
Ale zistil som teraz, že bude trochu problém s tým ako získať informácie odtiaľ, keďže {2} (kvantifikátor, ak si správne spomínam?) mi to zakryje posledný vstup a ja som tajne dúfal, že to spraví rekurzívne, že to bude n-tica v n-tice, ale akosi smola. Takže idem pátrať a bádať, aby som sa nemusel rozpisovať cez viac riadkov...
-
jasne, jinak bych to taky nedelal. Nicmene vyhoda toho testu je to, ze to testuje klidne zilion vstupu naraz (a taky mnohem rychlejc, nez bys to stacil odsipkovat)
ad problem: nejsem sem si jistej, ze ti rozumim, ale i tak gl.
-
Vyriešené nadobro.
No, chyba spočívala v tom, že mocnina bola vyžadovaná povinne, takže opravené to je nejako takto (narýchlo skopírované):
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import re
pattern = re.compile(r'''
^ # začiatok reťazcu
\( # číselné vyjadrenie je v zátvorke
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla
( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
) # nevyžadujeme ho povinne - vnútri bloku nemusí prísť k zhode
( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:\^|\*\*)? # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný
) # blok je u konca
( # nasledujúci blok zachytávame - jednotlivé vyjadrenie čísla
( # zachytávame číslo, ktoré násobí vyjadrenie
[-+]? # predpokladáme, že prvý znak bude znamienko, ale nemusí byť
\d* # ľubovolný číselný výraz, ktorý "násobí" hodnotu výrazu
) # nevyžadujeme ho povinne - vnútri bloku nemusí prísť k zhode
( # zachytávame jednotlivé premenné
([a-z]) # nejaké alfabetické vyjadrenie výrazu (písmeno), ktorý zachytávame
(?:\^|\*\*)? # ľubovolný "umocňovateľ"
(\d*) # mocniteľ
)+ # je striktne vyžadovaný
)
\) # koniec číselného vyjadrenia
(?:\^|\*\*)? # mocniteľ...
(\d+) # ľubovolná mocnina zátvorky
$ # koniec reťazcu
''', re.VERBOSE)
print(pattern.search(input()).groups())
Problém, ale stále mám v tom, že to tam držím zduplikované, aby som sa dostal k valídnemu výsledku pre analýzu, ale hlavne, že to ide. Už len tie testy :).