exakte Länge mit RegEx feststellen

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
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

ich habe eine String mit variabler Länge und ohne Whitepsaces, bei dem ich testen möchte, ob er mit exakt vier Zahl aufhört.

Mit

Code: Alles auswählen

re.match('\d{4}$',string)
funktioniert es nicht, weil das auf 'abcd01234' genau so passt wie auf 'abcd012345'.

Gruß, noisefloor
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Dann sag dem RegExp, dass er vor den Zahlen nur Buchstaben akzeptieren soll ;-)
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Besser nichtzahl:

Code: Alles auswählen

re.match('\D?\d{4}$',string)
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

Das dürfte auch nicht richtig funktionieren, da die Regex nur Strings der Länge 4 und 5 matcht.

Code: Alles auswählen

>>> print re.match('\D?\d{4}$', 'ab1234')
None
Mein Vorschlag:

Code: Alles auswählen

>>> reg = re.compile('(?:^|\D)(\d{4}$)')
>>> reg.search('ab1234').group(1)
'1234'
>>> print reg.search('ab12345')
None
MfG
HWK
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

irgendwas funktioniert nicht... und ich verstehe es nicht... :roll:

Code: Alles auswählen

text1 = 'abc12345'
text2 = 'abc1234'

re.match('\D?\d{4}$',text1)
#es wird kein match-Objekt zurückgegeben
re.match('\D?\d{4}$',text2)
#es wird kein match-Objekt zurückgegeben
re.search('\D?\d{4}$',text1)
#gibt ein match-Objekt
re.search('\D?\d{4}$',text2)
#gibt ein match-Objekt
EDIT: habe gerade erst das letzte Posting von HWK gelesen... werde ich mal probieren. :-)

Gruß, noisefloor
problembär

Könntest auch eine eigene kleine Funktion ohne RegExes schreiben, in der Du die letzten vier Stellen jeweils mit ".isdigit()" überprüfst.

Gruß
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

problembär hat geschrieben:Könntest auch eine eigene kleine Funktion ohne RegExes schreiben, in der Du die letzten vier Stellen jeweils mit ".isdigit()" überprüfst.

Gruß
Die davor sollen aber ja grad keine Digits sein!
Benutzeravatar
noisefloor
User
Beiträge: 3856
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Könntest auch eine eigene kleine Funktion ohne RegExes schreiben,
Klar, kann man. Aber man muss ja mindestens 2x slicen, um das zu testen. Geht, ist aber nicht elegant. :wink:

Gruß, noisefloor
BlackJack

@noisefloor: Einmal "slicen" reicht. Bei dem was vor den letzten vier Zeichen steht interessiert ja nur *ein* Zeichen -- dafür muss man nicht "slicen".
Benutzeravatar
snafu
User
Beiträge: 6740
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wenn man es in reinem Python schreiben möchte, dürfte dies alle Fälle abdecken:

Code: Alles auswählen

len(s) >= 4 and s[-4:].isdigit() and not s[-5:-4].isdigit()
Den letzten Slice mache ich so, weil er einen leeren String ergibt, wenn nur 4 Zeichen vorhanden sind und ich damit einen IndexError umgehe.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Code: Alles auswählen

import re

def s(s):
    return bool(re.search(r"(^|\D)\d{4}$", s))

assert s("1234")
assert not s("123")
assert not s("11234")

assert s("abc1234")
assert not s("abc123")
assert not s("abc11234")
Stefan
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

@sma: Entspricht das nicht dem, was ich bereits vorgeschlagen habe?
MfG
HWK
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

HWK hat geschrieben:@sma: Entspricht das nicht dem, was ich bereits vorgeschlagen habe?
Weitestgehend. Ich habe keine Gruppen. Manchmal schreibe ich Postings offline und/oder lese nicht alle Beiträge sorgfältig genug, um zu bemerken, dass mittlerweile mein Posting obsolete geworden ist. Und manchmal denke ich mir auch einfach, wenn ich's schon geschrieben habe, kann ich's auch posten. Das ist dann nicht als Kritik der vorherigen Beiträge zu werden.

Stefan
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

sma hat geschrieben:Ich habe keine Gruppen.
Doch: (^|\D).
Den Rest bei mir habe ich nur zugefügt, weil ich nicht wusste, ob der OP die letzten 4 Ziffern noch weiter verwenden will.
Ich habe Deinen Post auch nicht als Kritik aufgefasst, wollte Dich aber trotzdem auf das Überlesen meines Posts aufmerksam machen. :wink:
MfG
HWK
Benutzeravatar
jbs
User
Beiträge: 953
Registriert: Mittwoch 24. Juni 2009, 13:13
Wohnort: Postdam

Was meint denn `(^|\D)`.
Also \D ist klar, aber ich verstehe hier denn Sinn von ^ gerade nicht.
[url=http://wiki.python-forum.de/PEP%208%20%28%C3%9Cbersetzung%29]PEP 8[/url] - Quak!
[url=http://tutorial.pocoo.org/index.html]Tutorial in Deutsch[/url]
Zap
User
Beiträge: 533
Registriert: Freitag 13. Oktober 2006, 10:56

jbs hat geschrieben:Was meint denn `(^|\D)`.
Also \D ist klar, aber ich verstehe hier denn Sinn von ^ gerade nicht.
Damit eine vierstellige Zahl am Anfang des Strings akzeptiert wird.

Code: Alles auswählen

In [2]: import re

In [3]: re.match(r"^\d{4}$", "1234")
Out[3]: <_sre.SRE_Match object at 0x012FC3A0>

In [4]: re.match(r"\D\d{4}$", "1234")
In [5]:
Antworten