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.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Hallo Zusammen,

ich habe in der Schule die Aufgabe bekommen, zu überprüfen, ob ein übergebenes Wort mit einem regulären Ausdruck übereinstimmt.
Beispielsweise also:

Alphabet: "a","b"
Regulärer Ausdruck: "a(a | b | c)* b")
Wort: "abcb"
Rückgabe: True

Der Anfang ist ja relativ verständlich. Ich muss ja nur schauen, ob das erste Element des Wortes = a ist. Jedoch komme ich danach nicht weiter. (a | b | c)* bedeutet ja, dass beliebig oft entwerder a oder b oder c folgt. Jedoch tue ich mir mit der Implementierung dessen sehr schwer; vor allem weil das ganze noch variabel für andere Ausdrücke ausführbar sein soll. Könnte mir jemand vielleicht etwas auf die Sprünge helfen?
Im Voraus vielen Dank!
__deets__
User
Beiträge: 14540
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich kann mir nicht vorstellen, dass *du* eine Zustandsmaschine fuer regulaere Ausdruecke implementieren sollst. Sondern das du das Modul "re" benutzen sollst.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Hallo, so wie ich es verstanden habe, soll ich eine Klasse für Reguläre Ausdrücke implementieren und eine Methode davon soll eben die o.g. sein.
Gibt es denn im Re Modul eine Methode zur Überprüfung?
Zuletzt geändert von Unplayable am Mittwoch 9. Oktober 2019, 17:32, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Was sollst Du genau tun? Einfach den gegebene Regulären Ausdruck auf einen String anwenden?
Was hast Du schon versucht? Code? Warum Klasse? Welche Methoden soll die haben?

EDIT: ja, das re-Modul ist dazu da, um Strings gegen reguläre Ausdrücke zu testen.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Sirius3 hat geschrieben: Mittwoch 9. Oktober 2019, 17:32 Was sollst Du genau tun? Einfach den gegebene Regulären Ausdruck auf einen String anwenden?
Was hast Du schon versucht? Code?

genau, das ist eine der Methoden die ich implementieren soll. Ich bin mir aber noch unsicher, ob ich das re Modul benutzen darf, daher habe ich noch einmal nachgefragt.
Ich soll in dieser Methode schauen ob das übergebene Wort zur Sprache passt und dann True oder False zurückliefern.

Bis jetzt sieht meine Klasse so aus:

Code: Alles auswählen

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

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

    def print_regau(self):
        print(self.regau)

    def zerlege_wort(self, wort, liste):
        for i in wort:
            liste.append(i)
        return liste

    def passendes_wort(self, wort):
        #liste = zerlege_wort(self, wort, liste)


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

ra.print_alphabet()
ra.print_regau()
print(ra.zerlege_wort("abcb", []))
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

[Edit] ich habe es wohl falsch aufgenommen. Wir dürfen das RE modul benutzen.
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Was soll den `Rega` bedeuten? regau soll bestimmt regulaerer_ausdruck heißen. Benutze keine Abkürzungen, weil das nur das Lesen erschwert.

In der Methode `print_alphabet` sollte `i` dann `buchstabe` heißen. `i` wird üblicherweise für einen Index benutzt. Solche `print`-Methoden sind aber in Klassen eher unüblich, weil man flexibler selbst `print(xy)` aufruft, wenn man etwas ausgeben will.
In `zerlege_wort` ist dann i wohl auch wieder buchstabe, daran erkennst Du auch gleich, dass diese for-Schleife die einzelnen Buchstaben des Wortes `wort` liefert.
`liste` ist dann zu generell benannt. Was soll denn der Inhalt der Liste sein? Dann änderst Du den Inhalt der Liste. Das sollte man möglichst vermeiden. Übergebene Parameter sollten sich nicht verändern. Hier würdest Du einfach eine neue Liste zurückgeben:
Kurz geht das so:

Code: Alles auswählen

    def zerlege_wort_in_buchstaben(self,wort):
        return list(wort)
Nun ist das aber keine sinnvolle Methode, weil sie nichts mit `self` macht, also gar keinen Bezug zur Klasse hat. Das ist auch als Funktion wenig sinnvoll, weil list(wort) für geübte Python-Programmierer viel einfacher zu verstehen ist. Im übrigen kann auch an den meisten Stellen, wo man so eine Liste benutzen würde auch gleich das wort direkt verwenden.

Und was soll nun `passendes_wort` genau machen?
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Das mit "zerlege_wort" habe ich nur gemacht, weil ich dachte, dass das RE Modul verboten ist.

Passendes_wort soll wie gesagt folgendes machen:
Man übergibt das Wort (z.B. "abcc") und dann soll mithilfe des regulären Ausdrucks geschaut werden, ob das Wort zur Sprache gehört, oder nicht. Wenn ja = True, andernfalls = False.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Was muss man denn bei der Fullmatch Funktion angeben? Ich habe jetzt meinen Ausdruck mit re.compile übergeben. Laut der Python Hilfe muss ich ja jetzt mit fullmatch schauen, ob der ganze String gültig ist. In welcher Reihenfolge wird das denn geschrieben? re.fullmatch ....?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Hast Du die Dokumentation dazu schon durchgelesen?
Da reicht eigentlich `help(re.fullmatch)`:
fullmatch(pattern, string, flags=0)
Try to apply the pattern to all of the string, returning
a match object, or None if no match was found.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Okay, also müsste ich ja einfach schauen, ob ein Objekt zurückgegeben wird, oder nicht. Wenn ein Objekt zurückgegeben wird, dann True und wenn nicht, False. Sehe ich das richtig?
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Probier's aus.
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Okay, es hat funktioniert. Danke schon mal :)

Code: Alles auswählen

def passendes_wort(self, wort):
        if re.fullmatch("^a(a|b|c)*b$", wort) == None:
            return False
        else:
            return True
jetzt muss ich mir aber noch überlegen wie ich den Ausdruck vorher mit re.compile definiere, damit ich den nicht bei jeder Änderung in der Methode ändern muss
Sirius3
User
Beiträge: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast eine Klasse, die ein Attribut `regulaerer_ausdruck` hat.

Da die if-Bedingung schon einen Wahrheitswert liefert, kann man ihn auch gleich per `return` zurück geben (natürlich mit der umgekehrten Bedingung):

Code: Alles auswählen

return re.fullmatch("^a(a|b|c)*b$", wort) is not None
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Okay, danke. Aber ich persönlich wäre nur auf meinen Weg von selbst gekommen. Für die Feinheiten fehlt es mir noch an Übung
nezzcarth
User
Beiträge: 1634
Registriert: Samstag 16. April 2011, 12:47

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: 17750
Registriert: Sonntag 21. Oktober 2012, 17:20

@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: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ü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: 13108
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Jetzt noch ^ und $ entfernen. Was sollen die denn bewirken?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Unplayable
User
Beiträge: 51
Registriert: Mittwoch 24. Februar 2016, 22:09

Alles klar, danke für eure Hilfen :)
Antworten