Regulären Ausdruck in Python prüfen

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
nezzcarth
User
Beiträge: 753
Registriert: Samstag 16. April 2011, 12:47

Mittwoch 9. Oktober 2019, 18:32

Da in der Methode self nicht verwendet wird, kannst du eine staticmethod daraus machen. Reguläre Ausdrücke werden meist als Raw-Strings definiert (also: r"^a(a|b|c)*b$").
Sirius3
User
Beiträge: 10548
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 9. Oktober 2019, 18:40

@nezzcarth: das ist ja der Punkt, an dem der OP noch arbeiten muß, das konstanten Pattern variable zu machen, wenn ich richtig verstanden habe.

Allein das macht die Klasse aber noch nicht zu einer sinnvollen Klasse.

@Unplayable: Was willst Du denn mit dem Alphabet anfangen?
Benutzeravatar
snafu
User
Beiträge: 5926
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 9. Oktober 2019, 18:50

Übrigens: Wenn man re.fullmatch() nutzt, dann muss man nicht zusätzlich im Pattern angeben, dass der Ausdruck vom Anfang bis zum Ende treffen soll. Das ist doppelt gemoppelt, da man eh nur ein Fullmatch hat, wenn der Ausdruck zum gesamten String passt.

Also entweder re.match("^a(a|b|c)*b$") oder re.fullmatch("a(a|b|c)*b") nehmen... ;)
Benutzeravatar
__blackjack__
User
Beiträge: 4192
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 9. Oktober 2019, 19:11

Jetzt noch ^ und $ entfernen. Was sollen die denn bewirken?
“Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life.”
— Terry Pratchett, Jingo
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Mittwoch 9. Oktober 2019, 19:39

Alles klar, danke für eure Hilfen :)
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Mittwoch 9. Oktober 2019, 19:52

Ich habe noch eine kleine Verständnisfrage:

Wenn ich die Konstante ^a(a|b|c) *b$ in der Match Zeile manuell eingebe, dann gibt mir die Methode richtigerweise True zurück. Jetzt habe ich den Code wie folgt geschrieben:

Code: Alles auswählen

import re

class Rega:
    
    def __init__(self,alphabet, RA):
        self.alphabet = alphabet
        self.regulaerer_ausdruck = RA

    def print_alphabet(self):
        for i in self.alphabet:
            print(i)

    def regulaerer_ausdruck(self):
        return self.regulaerer_ausdruck

    def passendes_wort(self, wort):
        if re.match(ra.regulaerer_ausdruck, wort) == None:
            return False
        else:
            return True

ra = Rega(["a","b","c"], "^a(a|b|c) *b$")

ra.print_alphabet()

print(ra.regulaerer_ausdruck)
print(ra.passendes_wort("abcb"))
In der init Methode habe ich mir ja den regulären Ausdruck in self.regulaerer_ausdruck geschrieben. Diesen habe ich dann mit ra.regulaerer_ausdruck in der Match Zeile statt der Konstanten verwendet. Wenn ich das jetzt ausführe gibt er mir aber komischerweise False zurück. Normalerweise müsste doch aber auch True zurückkommen, weil der Ausdruck ja noch der gleiche ist, nur dieses Mal eben in einer Variablen steht. Übersehe ich da etwas?
Sirius3
User
Beiträge: 10548
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 9. Oktober 2019, 20:21

Dein Regulärer Ausdruck ist ja jetzt auch ein anderer.

RA ist kein sinnvoller Name für einen Parameter. Benutze keine Abkürzungen. Konvention ist auch, dass Variablennamen klein geschrieben werden. regulaerer_ausdruck wäre besser.
Die Methode `regulaerer_ausdruck` ist quatsch. Zum einen sollten Methodennamen eine Tätigkeit sein, weil sie ja was machen, zum anderen wird die Methode in __init__ von dem Attribut gleichen Namens überdeckt, zum dritten macht die Methode auch nichts sinnvolles, da sie nur etwas zurückgibt, was man auch direkt über Attributzugriff erreicht.

Was ist der Nutzen des Alphabets?
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Mittwoch 9. Oktober 2019, 20:28

Okay, ich werde es mir aneignen. Aber wieso ist der Ausdruck denn jetzt ein anderer? Ich habe ihn doch nur in eine Variable geschrieben? Den Nutzen des Alphabeths kann ich nicht sagen, wir sollen die Klasse nur als Übung programmieren.
Benutzeravatar
__blackjack__
User
Beiträge: 4192
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 9. Oktober 2019, 20:55

@Unplayable: Der reguläre Ausdruck ist jetzt ein anderer weil es eben nicht mehr der gleiche ist. *Warum* Du den verändert hast, musst Du schon selbst wissen. Bezihungsweise passt der in Deinem ersten Beitrag ja schon nicht auf die Beispieldaten. Auch Leerzeichen haben eine Bedeutung.
“Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life.”
— Terry Pratchett, Jingo
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Mittwoch 9. Oktober 2019, 21:09

Vielen Dank! Habe auf das Leerzeichen gar nicht geachtet
Benutzeravatar
snafu
User
Beiträge: 5926
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 9. Oktober 2019, 21:21

Das ist so ziemlich das übelste Beispiel für OOP, das ich seit langem gesehen habe... :o
Benutzeravatar
snafu
User
Beiträge: 5926
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 9. Oktober 2019, 21:29

Was mir noch fehlt, ist eine genauere Auswertung:

Code: Alles auswählen

if ra.passendes_wort("abcb") == True:
    passt = True
else:
    pass
if ra.passendes_wort("abcb") == False:
    passt_nicht = True
else:
    pass
try:
    if passt == True:
        print("Passt")
    else:
        if passt_nicht == True:
            print("Passt nicht")
        else:
            pass
except:
    print("Fehler")
Zuletzt geändert von snafu am Mittwoch 9. Oktober 2019, 21:32, insgesamt 1-mal geändert.
Benutzeravatar
__blackjack__
User
Beiträge: 4192
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 9. Oktober 2019, 21:31

Nochmal zum Alphabet: Das sollte kein Argument sein und vom Programmierer nicht angegeben werden müssen. Die Informationen stecken ja bereits im Muster des regulären Ausdrucks, und von da sollte man sich das auch holen wenn man es braucht.

Code: Alles auswählen

#!/usr/bin/env python3
import re
from sre_parse import LITERAL, parse as sre_parse, SubPattern


def iter_literals(nodes):
    for node in nodes:
        if isinstance(node, (tuple, list, SubPattern)):
            if node[0] == LITERAL:
                yield chr(node[1])
            else:
                yield from iter_literals(node)


class RegularExpression:
    def __init__(self, pattern):
        self._regex = re.compile(pattern)

    @property
    def pattern(self):
        return self._regex.pattern

    @property
    def alphabet(self):
        return "".join(sorted(set(iter_literals(sre_parse(self.pattern)))))

    def matches(self, text):
        return self._regex.fullmatch(text) is not None


def main():
    regular_expression = RegularExpression("a(a|b|c)*b")
    for character in regular_expression.alphabet:
        print(character)
    print(regular_expression.pattern)
    print(regular_expression.matches("abcb"))


if __name__ == "__main__":
    main()
“Give a man a fire and he's warm for a day, but set fire to him and he's warm for the rest of his life.”
— Terry Pratchett, Jingo
Sirius3
User
Beiträge: 10548
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 9. Oktober 2019, 21:53

@snafu: Vorsicht, Anfänger könnten die Ironie darin nicht verstehen.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Mittwoch 9. Oktober 2019, 21:57

Danke für die äußerst fachliche Hilfe! Aber ich habe es eben so als Arbeitsauftrag bekommen, an den ich mich halten soll, auch wenn das im Auge eines erfahrenen Programmierers keinen Sinn ergibt bzw keine gute Übung ist.
Antworten