re

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.
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 13:29

Hallo ich habe versucht mit re.search() etwas bestimmtes aus eine string ausgeben zu lassen, aber da mir re sehr neu ist weiss ich nicht wie ich es umsetzen soll.
Ich schreibe mal meinen string hier rein und markiere alles rot das ich nicht will und grün was ich ausgeben möchte.
"/bin/sh: 1: fff11&: not found"
könnte mir jemand helfen?
Benutzeravatar
sparrow
User
Beiträge: 1663
Registriert: Freitag 17. April 2009, 10:28

Mittwoch 4. Dezember 2019, 14:10

Code: Alles auswählen

text="/bin/sh: 1: fff11&: not found"
text.split(":")[-2].strip()
Sirius3
User
Beiträge: 11316
Registriert: Sonntag 21. Oktober 2012, 17:20

Mittwoch 4. Dezember 2019, 14:54

@Fire Spike: wie sieht das Muster aus, das Du suchen willst? Nur so kann man einen regulären Ausdruck schreiben. Was sind alle möglichen Strings, die Du hast und was möchtest Du aus all denen extrahiert haben?
Benutzeravatar
__blackjack__
User
Beiträge: 5144
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 4. Dezember 2019, 15:00

Ohne `re` unter der Annahme das die nicht gewünschten Anteile fest sind:

Code: Alles auswählen

In [1]: line = "/bin/sh: 1: fff11&: not found"                                  

In [2]: prefix = "/bin/sh: 1: "                                                 

In [3]: suffix = " not found"                                                   

In [4]: if line.startswith(prefix) and line.endswith(suffix): 
   ...:     print(line[len(prefix):-len(suffix)]) 
   ...:                                                                         
fff11&:
Wenn man das unbedingt mit `re` lösen möchte, müsstest Du mehr darüber erzählen was die Rahmenbedingungen sind, also was da in den roten und grünen Teilen variabel ist und nach welchem Muster(n) das varriieren kann, denn genau *das* muss man dann ja mit einem regulären Ausdruck formulieren.
long long ago; /* in a galaxy far far away */
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 15:08

das grüne kann alles auf der Tastatur sein und auch jede länge haben, das rote ist immer das selbe.
Hilft das?
Benutzeravatar
__blackjack__
User
Beiträge: 5144
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 4. Dezember 2019, 15:32

Na dann greift meine nicht-re-Lösung doch prima. Ein regulärer Ausdruck würde da keinen Gewinn bringen, wäre aber wirklich sehr simpel.
long long ago; /* in a galaxy far far away */
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 15:55

ich habe gerade gemerkt das die blau markierte Zahl varieren kann. Sie kann zufällig sein, auch in der Länge.
"/bin/sh: 1: fff11&: not found"
Dann geht dein Script ja nicht mehr :roll:
Benutzeravatar
pillmuncher
User
Beiträge: 1164
Registriert: Samstag 21. März 2009, 22:59
Wohnort: München

Mittwoch 4. Dezember 2019, 16:22

Fire Spike hat geschrieben:
Mittwoch 4. Dezember 2019, 15:55
ich habe gerade gemerkt das die blau markierte Zahl varieren kann.
Naja, so schwer ist das auch nicht:

Code: Alles auswählen

>>> text="/bin/sh: 1: fff11&: not found"
>>> text.split(":")[0].strip()
'/bin/sh'
>>> text.split(":")[1].strip()
'1'
>>> text.split(":")[2].strip()
'fff11&'
>>> text.split(":")[3].strip()
'not found'
Oder ohne unnötige Wiederholungen:

Code: Alles auswählen

>>> parts = [s.strip() for s in text.split(":")]
>>> parts
['/bin/sh', '1', 'fff11&', 'not found']
In specifications, Murphy's Law supersedes Ohm's.
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 16:30

Danke Pillmuncher könntest du vielleicht doch noch eine re lösung posten? Dann weiss ich wenigstens wie ich so etwas mit re lösen könnte ;)
Benutzeravatar
__blackjack__
User
Beiträge: 5144
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 4. Dezember 2019, 16:33

@Fire Spike: Was hast Du denn bisher versucht? Und wie/womit? Schau Dir mal https://regex101.com/ an. Es gibt auch andere Online-Dienste und auch Desktopanwendungen um beim Entwickeln von regulären Ausdrücken zu helfen.
long long ago; /* in a galaxy far far away */
LeSchakal
User
Beiträge: 2
Registriert: Dienstag 5. Februar 2019, 23:40

Mittwoch 4. Dezember 2019, 18:55

@pillmuncher: Wenn im gesuchten Text allerdings ein Doppelpunkt vorkommt, ist die Lösung nicht mehr so ideal.
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 20:56

@__blackjack__ danke für deinen link, aber wenn ich auf Python umstellen will wird alles Weiss und es passiert nichts mehr.
Ich versuchte bisher das:

Code: Alles auswählen

print(re.search(f"/bin/sh:[a-z+A-Z+0-9+{string.punctuation}] not found", "/bin/sh: 1: fff11&: not found"))
@LeSchakal das ist wirklich ein Problem.
Benutzeravatar
__blackjack__
User
Beiträge: 5144
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Mittwoch 4. Dezember 2019, 21:54

@Fire Spike: Die Seite verwendet JavaScript. Falls Du das blockierst müsstest Du es für die Seite freischalten.

Innerhalb von eckigen Klammern gelten in regulären Ausdrücken deutlich andere Regeln als ausserhalb. Und Du hast Glück das in `string.punctuation` vor dem "]" ein "\" steht, sonst wäre das syntaktisch kein korrekter regulärer Ausdruck. Der "\" hat eine besondere Bedeutung in regulären Ausdrücken auch innerhalb von eckigen Klammern, das heisst ein "\" selbst ist in dem Muster nicht enthalten. Und bei ",-." hast Du Glück, dass das gerade genau diese drei Zeichen beschreibt, denn auch das "-" hat eine besondere Bedeutung innerhalb von eckigen Klammern, die Du ja benutzt.

Problem ist, das der blaue Teil hier

/bin/sh:[a-zA-Z0-9+!"#$%&'()*+,-./:;<=>?@[\]^_`{|}~] not found

für *genau* *ein* Zeichen steht. Und zwar eines aus der Zeichenmenge die innerhalb der eckigen Klammern beschrieben wird.

Das ist aber alles viel zu kompliziert. Warum willst Du da alle Möglichen Zeichen aufzählen? Kann es denn nicht *irgendein* Zeichen sein, und davon dann beliebig viele zwischen dem Prä- und dem Suffix‽ Das wäre *total simpel*.
long long ago; /* in a galaxy far far away */
Benutzeravatar
Fire Spike
User
Beiträge: 208
Registriert: Montag 13. Mai 2019, 16:05
Wohnort: Erde

Mittwoch 4. Dezember 2019, 22:09

Ich habe nur alle aufgelistet weil ich nicht weiss wie ich es sonst machen soll und die beliebige länge weiss ich nicht wie ich es machen soll.:roll:
Ich habe versucht den AD Blocker und den Malwarebytes Browser Guard zu deaktivieren , leider hilft es nicht. Ich selbst blockiere kein Javascript.

Edit: Ich habe herausgefunden das ich ein "." für ein beliebiges Zeichen einsetzen kann, eine beliebige länge finde ich nicht.
Benutzeravatar
snafu
User
Beiträge: 6023
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 4. Dezember 2019, 23:00

Das re-Modul hat eine Online-Dokumentation: https://docs.python.org/3/library/re.html

Sucht man dort nach "any character", dann findet man folgendes:
(Dot.) In the default mode, this matches any character except a newline. If the DOTALL flag has been specified, this matches any character including a newline.
Somit muss man im regulären Ausdruck halt einen Punkt verwenden, um ein (nahezu) beliebiges Zeichen zu matchen. Für Wiederholungen mit mindestens einem Vorkommen benutzt man das Plus-Zeichen. Eine Kombination aus beidem lautet demnach .+. Wenn nichts mehr dahinter steht, dann trifft dies alles bis zum Zeilenende (ohne das abschließende \n). Andernfalls fügt man halt ein anderes Zeichen (oder Ausdruck) als Begrenzung ein. Aufpassen muss man in dem Zusammenhang mit dem Umfang des Treffers. Dazu solltest du dich mit den Stichwort "greedy" bzw "non-greedy" beschäftigen. Oft will man non-greedy als Verhalten haben und sollte somit ein Fragezeichen dahinter setzen, also in diesem Fall .+? schreiben, damit er nicht mehr als erwartet matcht.

Um jetzt z.B. Text innerhalb von Klammern zu finden, kann man folgendes nehmen:

Code: Alles auswählen

re.findall(r"\(.+?\)", text)
Den ersten Backslash braucht man zum Escapen, weil die öffnende Klammer sonst eine besondere Bedeutung hätte, was hier aber nicht gewünscht ist. Der zweite Backslash ist quasi freiwillig. Da kann man sich aussuchen, ob man alle Klammern escaped, wenn man tatsächlich die Klammer meint oder ob man das nur für die öffnenden Klammern so handhabt.

EDIT:
Wenn man wirklich nur an den Text will innerhalb der Klammern will, müsste man sogar innere Klammern setzen, um eine Gruppe zu definieren. Dann haben sie auch die besondere Bedeutung, die ich erwähnt hatte.

Code: Alles auswählen

re.findall(r"\((.+?)\)", text)
Und wenn man auch mit Klammern ohne Inhalt klar kommen will (kein Treffer), dann muss man es nochmals erweitern:

Code: Alles auswählen

re.findall(r"\(([^)]+)\)", text)
Wie man sieht, fangen reguläre Ausdrücke schon spätestens da an, so "richtig Spaß" zu machen...
Antworten