[Python-de] Regulärer Ausdrücke

Stefan Schwarzer sschwarzer at sschwarzer.net
Sam Jan 3 17:01:56 CET 2004


Hallo Stefan,

On Sat, 2004-01-03 14:55:20 +0100, Stefan J. Betz wrote:
> ich habe ein Programm in dem ich prüfen will ob ein übergebener Paramter
> eine IP ist, ich habe das "Problem" zwar gelöst, aber dennoch frage ich
> mich warum die RE:
> "[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}"
> 
> Nicht Funktioniert, aber die RE:
> "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$"
> 
> funktioniert einwandrei!
> [...]

Fritz hat ja schon etwas dazu geschrieben, warum der eine reguläre
Ausdruck funktioniert und der andere nicht.

Ich habe noch eine Anmerkung. Der "richtige" reguläre Ausdruck lässt
immer noch unsinnige IPs zu, z. B. 192.168.327.999 (die einzelnen
Bestandteile dürfen nur zwischen 0 und 255 liegen).

Evtl. reicht dir eine "Vorauswahl" schon, aber wenn du es genauer
haben willst, wird der reguläre Ausdruck schon komplizierter. Ich habe
sowas mal hinbekommen, aber fand es dann so unübersichtlich, dass ich
mir vorgenommen habe, das nie zu verwenden. ;-)

[Ich hab's eben nochmal ausprobiert; eine Gruppe (von 4) sollte sich
mit re.compile(r"^[1-9]|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]$")
indentifizieren lassen, aber wie gesagt, ist ziemlich unübersichtlich
(selbst, wenn es sich noch etwas "komprimieren" lässt, oder sogar dann
erst recht).]

Du kannst zur Kontrolle der IP aber auch ganz ohne Regex auskommen
(ungetesteter Code):

parts = ip.split('.')
try:
    numbers = [int(part) for part in parts if 0 <= int(part) <= 255]
    if len(numbers) != 4:
        raise ...
except ValueError:
    raise ...
    
Eine andere Möglichkeit ist, den Regex mit Gruppen zu verwenden und
die einzelnen Bestandteile zu untersuchen:

match = re.search(r"^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$", ip)
if match is None:
    raise ...
numbers = [int(part) for part in match.groups() if 0 <= int(part) <= 255]
if len(numbers) != 4:
    raise ...

Das ist nur eine Zeile weniger.

Noch ein Hinweis, falls du IPv6 einbeziehen willst: Das obige gilt für
IPv4; IPv6-IPs sind wiederum anders aufgebaut.

Stefan