Regex matching 5-digit substrings not enclosed with digits
I want to extract 5 continuous digits from the string
code I have written.
re.findall(r"((\D|^)*)\d\d\d\d\d((\D|$)*)", s)
but it can not pass the string
"Helpdesk-Agenten (m/w) Kennziffer: 12966"
The expected result is:
12966
Example 2:
#input
"Helpdesk-Agenten (m/w) Kennziffer: 12966abc"
# expected
12966
Example 3:
#input
"Helpdesk-Agenten (m/w) Kennziffer: 12966345"
# expected
"" (because the length of continuous digits is longer than 5)
Solution 1:
Your current regex (((\D|^)*)\d\d\d\d\d((\D|$)*)
) used with re.findall
won't return the digit chunks because they are not captured. More, the (\D|^)*
and
(\D|$)*
parts are optional and that means they do not do what they are supposed to do, the regex will find 5 digit chunks inside longer digits chunks.
If you must find 5 digit chunk not enclosed with other digits, use
re.findall(r"(?<!\d)\d{5}(?!\d)", s)
See the regex demo
Details:
-
(?<!\d)
- no digit is allowed before the current location -
\d{5}
- 5 digits -
(?!\d)
- no digit allowed after the current location.
Solution 2:
Using word boundary (\b
), which match at beginning / end of the word:
>>> re.findall(r"\b\d\d\d\d\d\b", "Helpdesk-Agenten (m/w) Kennziffer: 12966")
['12966']
\d\d\d\d\d
can be replaced with \d{5}
:
>>> re.findall(r"\b\d{5}\b", "Helpdesk-Agenten (m/w) Kennziffer: 12966")
['12966']
UPDATE If you need to get 12966
out of 12966abc
, see Wiktor Stribiżew's answer which use negative lookaround assertions.
or
>>> [match.group(2) for match in re.finditer(r'(\D|^)(\d{5})(\D|$)', '12345abc')]
['12345']
or combining simple regular expression with list comprehension:
>>> [match for match in re.findall(r'\d+', '12345abc') if len(match) == 5]
['12345']