Regex to satisfy both string conditions

Viewed 139

I have hostnames that do not have the same length/convention:

tor1er1
tor1x1ms1

For 'tor1er1', we can break it down:

'tor' = region
'1' = environment
'er' = type
'1' = number for the device

For 'tor1x1ms1' we can break it down:

'tor' = region
'1' = environment
'x1' = cross connect
'er' = type
'1' = number for the device

As you can see, there is an extra 'x1' for cross connect when it comes to tor1x1ms1. I'm trying to forumlate a regular expression to accommodate both type of strings. I've tried:

import re
hostname = 'tor1er1'
m = re.match(r"([a-zA-Z]+)([0-9]+)([a-zA-Z]+)([0-9]+)([a-zA-Z]+)([0-9]+)",hostname)

Because the length doesn't match the expression expected. I would like to be able to access each groups to pull the information. For example:

region = m.groups(1)
environment = m.groups(2)
2 Answers

As x and 1 are both in its own capturing group, you can make both of them optional at once so you can keep using the group number for the same data.

You could consider anchors or word boundaries \b to prevent the match being part of a longer word.

([a-zA-Z]+)([0-9]+)(?:([a-zA-Z]+)([0-9]+))?([a-zA-Z]+)([0-9]+)

Regex demo

You may find it convenient to use named capture groups for this. You can do that with the following regular expression.

r'^(?P<reg>[a-z]{3})(?P<env>\d)(?:(?P<xcon>[a-z]\d))?(?P<type>[a-z]{2})(?P<nbr>\d)'

For the two example strings given in the question the regex provides the following results.

Full match   : "tor1er1"
Group `reg`  : "tor"
Group `env`  : "1"
Group `type` : "er"
Group `nbr`  : "1"

Full match   : "tor1x1ms1"
Group `reg`  : "tor"
Group `env`  : "1"
Group `xcon` : "x1"
Group `type` : "ms"
Group `nbr`  : "1"

Start your engine!

Python's regex engine performs the following operations.

^                   : match beginning of string
(?P<reg>[a-z]{3})   : match 3 lc letters and save to
                      capture group 'reg'
(?P<env>\d)         : match 1 digit and save to capture
                      group 'env'
(?P<xcon>[a-z]\d)?  : match 1 lc, letter 1 digit, save to
                      capture group 'xcon', make optional
(?P<type>[a-z]{2})  : match 2 lc letters, save to
                      capture group 'type'
(?P<nbr>\d)         : match 1 digit, save to
                      capture group 'nbr'
Related