Seite 1 von 1

Den folgenden re.search vereinfachen

Verfasst: Samstag 31. Oktober 2020, 21:48
von greetings1

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?

Re: Den folgenden re.search vereinfachen

Verfasst: Samstag 31. Oktober 2020, 22:09
von narpfel
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.

Re: Den folgenden re.search vereinfachen

Verfasst: Samstag 31. Oktober 2020, 22:39
von greetings1
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

Re: Den folgenden re.search vereinfachen

Verfasst: Samstag 31. Oktober 2020, 23:11
von sparrow
@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.

Re: Den folgenden re.search vereinfachen

Verfasst: Sonntag 1. November 2020, 00:10
von __blackjack__
@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.