Seite 1 von 2

Zahl in String finden (gelöst)

Verfasst: Montag 13. Oktober 2008, 08:40
von Nergal
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(...)?

Verfasst: Montag 13. Oktober 2008, 08:50
von Darii
Die Doku ist dein Freund.

Ansonsten geht natürlich auch immer

Code: Alles auswählen

if "12" in "Hallo Nr. 12!":
    print "Juhuu!"

Verfasst: Montag 13. Oktober 2008, 08:58
von Nergal
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....

Verfasst: Montag 13. Oktober 2008, 08:59
von BlackJack
Schau mal ins `re`-Modul und dessen Dokumentation.

Verfasst: Montag 13. Oktober 2008, 09:05
von .robert
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

Verfasst: Montag 13. Oktober 2008, 09:11
von Nergal
.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.

Verfasst: Montag 13. Oktober 2008, 09:14
von .robert
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: )

Verfasst: Montag 13. Oktober 2008, 09:57
von .robert
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

Verfasst: Montag 13. Oktober 2008, 11:33
von .robert
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:

Verfasst: Montag 13. Oktober 2008, 13:03
von 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']

Verfasst: Montag 13. Oktober 2008, 13:24
von .robert
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.

Verfasst: Montag 13. Oktober 2008, 13:47
von BlackJack
Meine "Lösung" wäre nicht wild irgendwelche regulären Ausdrücke für ein Problem zu schreiben, das es gar nicht gibt. ;-)

Verfasst: Montag 13. Oktober 2008, 13:49
von __marcus__
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.

Verfasst: Montag 13. Oktober 2008, 14:15
von .robert
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:

Verfasst: Montag 13. Oktober 2008, 18:13
von str1442
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'

Verfasst: Montag 13. Oktober 2008, 21:59
von snafu
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:

Verfasst: Freitag 17. Oktober 2008, 08:30
von da.dom
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?

Verfasst: Freitag 17. Oktober 2008, 08:45
von snafu
@da.dom:

Code: Alles auswählen

re.findall('((?:\d{1,3}[.]){3}\d{1,3})', s)

Verfasst: Freitag 17. Oktober 2008, 08:57
von da.dom
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}

Verfasst: Freitag 17. Oktober 2008, 10:17
von snafu
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