Zahl in String finden (gelöst)

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.
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Hallo,

ich bin Neuling im Umgang mit Python und habe eine sicherlich recht simple Frage.

Ich habe einen String, in dem evtl. eine Zahl vorhanden ist. Nun möchte ich diese Zahl herrausfinden und nicht den String Zeichen für Zeichen durchgehen. Gibt es dafür in Python eine schnellere Möglichkeit bzw. gibt es sowas wie ein IndexOf(...)?
Zuletzt geändert von Nergal am Montag 13. Oktober 2008, 09:11, insgesamt 1-mal geändert.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Die Doku ist dein Freund.

Ansonsten geht natürlich auch immer

Code: Alles auswählen

if "12" in "Hallo Nr. 12!":
    print "Juhuu!"
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

Danke für die schnelle Hilfe.

Das Problem ist nun nur noch, daß ich nicht im vorraus weiß, welche Zahl vorhanden ist. Format ist immer x.x.x....
BlackJack

Schau mal ins `re`-Modul und dessen Dokumentation.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

ungetestet:

Code: Alles auswählen

import re
zahlen=re.findall('([0-9]*)', "text mit zahl 2 und auch ne 12 und ne 14")
print zahlen
Nergal
User
Beiträge: 72
Registriert: Montag 6. Oktober 2008, 14:02

.robert hat geschrieben:ungetestet:

Code: Alles auswählen

import re
zahlen=re.findall('([0-9]*)', "text mit zahl 2 und auch ne 12 und ne 14")
print zahlen
Danke, genau das habe ich gebraucht ;)

Hab mal aus dem * ein + gemacht, da er sonst auch zich Leerstrings mitnimmt.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Nergal hat geschrieben:Hab mal aus dem * ein + gemacht, da er sonst auch zich Leerstrings mitnimmt.
Ähm, oh ja, stimmt, "+" ist besser :oops:

(nächstes mal lasse ich das selber ein mal durchlaufen, dann fällt mir sowas auch auf :wink: )
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Auch noch mal für Kommazahlen:

Code: Alles auswählen

import re
text = "text mit zahl 2 und auch ne 12 und ne 134364 1,3 1.5 2,56 78.545"
zahl=re.findall('\d+[,.]\d+|\d+', text)
print zahl
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

Man hat ja in der Mittagspause nichts besseres zu tun :roll:

Code: Alles auswählen

import re
text = "text mit zahl 2 und auch ne -12 und ne 134364 1,3 +1.5 -2,56 78.545"
zahl=re.findall('[+-]?\d+[,.]?\d*', text)
print zahl
:wink:
BlackJack

Naja…

Code: Alles auswählen

In [255]: text = 'Die ganze Zahl 5. Hausnummer 43-45. Localhost = 120.0.0.1'

In [256]: re.findall(r'[+-]?\d+[,.]?\d*', text)
Out[256]: ['5.', '43', '-45.', '120.0', '0.1']
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

BlackJack hat geschrieben:Naja…
Ab hier müsste man mMn anfangen, genauer zu spezifizieren, was gefunden, was nicht gefunden und vor allem was wie gefunden werden soll, um die RE zu verbessern.
Was soll denn aus 43-45 werden? ['43', '45'] oder ['43-45']?
Und ist eine IP eine Zahl, oder 4 Zahlen?

Unter der gegebenen Spezifikation (einfach Zahlen finden) ist meine Lösung schon korrekt.
Alles weitere wären in meinen Augen Spezialfälle...

Aber wenn du eine bessere Lösung parat hast, würde ich die gerne sehen.
BlackJack

Meine "Lösung" wäre nicht wild irgendwelche regulären Ausdrücke für ein Problem zu schreiben, das es gar nicht gibt. ;-)
__marcus__
User
Beiträge: 92
Registriert: Mittwoch 10. September 2008, 22:10
Wohnort: Hamburg

Nergal hat geschrieben:Format ist immer x.x.x....
Wobei man da schon gleich sagen kann, dass man auch wissen muss, was an Stelle dieser Punkte am Ende kommt.
.robert
User
Beiträge: 274
Registriert: Mittwoch 25. April 2007, 17:59

BlackJack hat geschrieben:Meine "Lösung" wäre nicht wild irgendwelche regulären Ausdrücke für ein Problem zu schreiben, das es gar nicht gibt. ;-)
Da ich mich bis jetzt erfolgreich davor gedrückt hatte, mich mit Regulären Ausdrücken zu beschäftigen, hatte ich ein ganz klein wenig gehofft, hier, vor allem weil der Threadstarter zufrieden zu seien scheint, ein wenig rum zu spielen und vor allem zu lernen zu können.
Ich hatte doch wirklich angefangen zu überlegen wie wohl eine RE aussieht, die deinen Beispielen genügt.
Tja, ich werde meine Ergebnisse dann wohl für mich behalten...
:roll:
Benutzeravatar
str1442
User
Beiträge: 520
Registriert: Samstag 31. Mai 2008, 21:13

Strings haben auch die str.isdigit() methode. Dazu müsste man zwar über jedes Zeichen iterieren, aber grade die String Methoden sollen doch gegebenüber zb re deutlich schneller sein.

Code: Alles auswählen

>>> a = filter(lambda x: x.isdigit(), "Hallo152!")
>>> a
'152'
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn eine Zahl alles bis zum nächsten Nicht-Digit ist, würde ich's so machen:

Code: Alles auswählen

In [11]: s = 'Die ganze Zahl 5. Hausnummer 43-45. Localhost = 120.0.0.1'

In [12]: re.findall('\d+', s)
Out[12]: ['5', '43', '45', '120', '0', '0', '1']
Bei Beachtung möglicher Vorzeichen so:

Code: Alles auswählen

re.findall('[+-]?\d+', s)
Spätestens ab hier wird's aber speziell und es bedarf einer Äußerung des OP, was Zahlen im weitesten Sinne sein sollen. Ein passendes Beispiel wäre wie immer hilfreich. :)

EDIT:
Nergal hat geschrieben:Das Problem ist nun nur noch, daß ich nicht im vorraus weiß, welche Zahl vorhanden ist. Format ist immer x.x.x....
Soll x.x.x als zusammenhängender String aufgenommen werden oder jede Zahl einzeln?

Also "bla1.2.3blupp" als ['1', '2', '3'] oder als '1.2.3'?

EDIT2: Oh, wurde ja schon ziemlich an Anfang gelöst. :oops:
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

Hab dazu mal ne schnelle Frage, darum schreibe ich sie mal drunter:

Will IP Adressen Filtern, und hab (noch) so keine Ahnung von Regulären Ausdrücken

Code: Alles auswählen

s="Zwei IP Adresse: Nr 1 : 192.168.2.1 und Nr 2 : 10.0.0.1"
print re.findall("[0-9\.]+",s)
>> ['1', '192.168.2.1', '2', '10.0.0.1']
Findet meinte IP Adressen, aber auch die Zahlen die keine sind?

Und, warum:

Code: Alles auswählen

print re.findall("[0-9\.*]",s)
>> Liefert alle Zahlen

Code: Alles auswählen

print re.findall("[0-9\.]*",s)
>> Liefer auch noch alle Leerzeichen und keine Punkte?
Zuletzt geändert von da.dom am Freitag 17. Oktober 2008, 08:49, insgesamt 1-mal geändert.
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@da.dom:

Code: Alles auswählen

re.findall('((?:\d{1,3}[.]){3}\d{1,3})', s)
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

snafu hat geschrieben:@da.dom:

Code: Alles auswählen

re.findall('((?:\d{1,3}[.]){3}\d{1,3})', s)
*schnauf* Kannst du dir die Mühe machen und einige Zeichen erklären?

?: >> Vertehe bei dem Punkt die Doku nicht besonders gut
\d >> alle decimalen Zeichen (alternativ mit demselben Ergebnis: [0-9]?)
{1,3} >> Wiederholung, Zahl kann 1-3 mal vorkommen
die Klammern um den ersten Ausdruck >> Gruppierung die 3 mal vorkommen kann, also 3Zahlen mit einem . darf 3 mal vorkommen, und das letzte Element hat keinen FolgePunkte, also kommt das noch mal dahinter (\d{1.3}
Benutzeravatar
snafu
User
Beiträge: 6731
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

da.dom hat geschrieben:?: >> Vertehe bei dem Punkt die Doku nicht besonders gut
Gibt es nicht als Gruppe aus, auch wenn es als Gruppe definiert werden musste. Probier's mal ohne. ;)
da.dom hat geschrieben:\d >> alle decimalen Zeichen (alternativ mit demselben Ergebnis: [0-9]?)
Richtig, matcht wenn das Zeichen eine Zahl ist. "d" steht hierbei für "digit".
da.dom hat geschrieben:{1,3} >> Wiederholung, Zahl kann 1-3 mal vorkommen
Ganz genau.
da.dom hat geschrieben:die Klammern um den ersten Ausdruck >> Gruppierung die 3 mal vorkommen kann, also 3Zahlen mit einem . darf 3 mal vorkommen, und das letzte Element hat keinen FolgePunkte, also kommt das noch mal dahinter (\d{1.3}
So siehts auch. Warum fragst du überhaupt? ;)

Übrigens weiß ich das ganz nur, weil ich vor ein paar Tagen fast die selbe Frage gestellt habe: http://www.python-forum.de/topic-16358.html
Antworten