Den folgenden re.search vereinfachen

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.
Antworten
greetings1
User
Beiträge: 51
Registriert: Donnerstag 22. Oktober 2020, 18:19

Code: Alles auswählen

import re

with open("hallo.txt") as f:
    for line in f:
        x = re.search(r"^([-+]?\d+) (.+) ([-+]?\d+)$", line)
        if x:
            print(f"|||{int(x.group(1))}|{int(x.group(3))}|{x.group(2)}|||")
lassen sich darin vielleicht noch Zeilen einsparen? Kann ich Tuple aus line und re.search definieren?
narpfel
User
Beiträge: 691
Registriert: Freitag 20. Oktober 2017, 16:10

Ich würde das komplett ohne reguläre Ausdrücke machen:

Code: Alles auswählen

from contextlib import suppress


def main():
    with open("hallo.txt") as lines:
        for line in lines:
            with suppress(ValueError):
                first_number, rest = line.split(" ", 1)
                middle_part, last_number = rest.rsplit(" ", 1)
                print(f"|||{int(first_number)}|{int(last_number)}|{middle_part}|||")


if __name__ == "__main__":
    main()
Wenn `middle_part` keine Leerzeichen enthalten darf, kann man das `split` und `rsplit` auch einfach als

Code: Alles auswählen

first_number, middle_part, last_number = line.split()
schreiben.
greetings1 hat geschrieben: Samstag 31. Oktober 2020, 21:48 Kann ich Tuple aus line und re.search definieren?
Ja, aber warum?

Code: Alles auswählen

foo = line, re.search
Jetzt ist `foo` ein Tupel aus `line` und `re.search`. Wenn das nicht das ist, was du willst, müsstest du deine Frage so formulieren, dass man nicht raten muss, was du willst.
greetings1
User
Beiträge: 51
Registriert: Donnerstag 22. Oktober 2020, 18:19

Der "middle_part" kann Leerzeichen enthalten.

> dass man nicht raten muss, was du willst

Hab ich doch geschrieben, ob man das mit weniger Zeilen schreiben könnte...

Hier mal ein Beispiel für "hallo.txt":

Code: Alles auswählen

45 hallo du daa 67
89 moin 1010
-15 lang weil 111ig +16
Benutzeravatar
sparrow
User
Beiträge: 4538
Registriert: Freitag 17. April 2009, 10:28

@greetings1: Die Nachfrage von narpfel bezog sich offensichtlich auf eine Frage "Kann ich Tuple aus line und re.search definieren?".

Wie genau stellst du dir das denn vor, bei einer Zeile weitere Zeilen einzusparen? Weniger als eine Zeile geht doch nicht?

Ich persönlich sehe das wie narpfel: Wenn der Sachverhalt nicht sehr komplex ist, würde ich auf die normalen Zeichenkettenoperationen zurückgreifen. Wenn hier nicht geprüft werden muss. Im Beispiel sind alle Zeilen "gültig", deshalb sehe ich nicht, warum man sie nicht splitten sollte.

Code: Alles auswählen

>>> a
'-15 lang weil 111ig +16'
>>> first, *middle, last = a.split()
>>> first
'-15'
>>> middle
['lang', 'weil', '111ig']
>>> last
'+16'
Das finde ich sehr viel weniger komplex zu lesen als den regulären Ausdruck.
Benutzeravatar
__blackjack__
User
Beiträge: 14053
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@greetings1: Den regulären Ausdruck kann man um zwei Zeichen kürzen wen man `re.fullmatch()` statt `re.search()` verwendet.

Ansonsten sehe ich das wie meine Vorredner: `split()` und `rsplit()` beziehungsweise `partition()` und `rpartition()` wären da meine Wahl.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Antworten