3
votes

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)
2
maybe you could provide more examples of matches? should it match 12345abc? - Jean-François Fabre♦
@Jean-FrançoisFabre thanks for the comment, added two examples - Hello lad
Here is another similar question stackoverflow.com/questions/16348538/… - kasravnd

2 Answers

6
votes

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.
4
votes

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']