2

Following regex matches both 59-59-59 and 59-59-59-59 and outputs only 59 The intent is to match four and only numbers followed by - with the max number being 59. Numbers less than 10 are represented as 00-09.

print(re.match(r'(\b[0-5][0-9]-{1,4}\b)','59-59-59').groups())
--> output ('59-',)

I need a pattern match that matches exactly 59-59-59-59

and does not match 59--59-59or 59-59-59-59-59

2
  • ^[0-5][0-9](?:-[0-5][0-9]){3}$ Commented Feb 15, 2019 at 10:48
  • If all you need is validate a whole string of 4 --separated numbers, use re.match(r'[0-5][0-9](?:-[0-5][0-9]){3}$', s). If there can be 1 to 4 of the numbers replace {3} with {0,3}. If you need to get the numbers after validation, use s.split('-') after the string validation passes. Commented Feb 15, 2019 at 11:01

2 Answers 2

3

Try using the following pattern, if using re.match:

[0-5][0-9](?:-[0-5][0-9]){3}$

This is phrased to match an initial number starting with 0 through 5, followed by any second digit. Then, this is followed by a dash and a number with the same rules, this quantity three times exactly. Note that re.match anchor at the beginning by default, so we only need an ending anchor $.

Code:

print(re.match(r'([0-5][0-9](?:-[0-5][0-9]){3})$', '59-59-59-59').groups())

('59-59-59-59',)

If you intend to actually match the same number four times in a row, then see the answer by @Thefourthbird.

If you want to find such a string in a larger text, then consider using re.search. In that case, use this pattern:

(?:^|(?<=\s))[0-5][0-9](?:-[0-5][0-9]){3}(?=\s|$)

Note that instead of using word boundaries \b I used lookarounds to enforce the end of the "word" here. This means that the above pattern will not match something like 59-59-59-59-59.

Sign up to request clarification or add additional context in comments.

4 Comments

This will also match 59-59-59-59 in the string 59-59-59-59-59
@Tim Biegeleisen: Why does print(re.match(r'(\b(?:-[0-5][0-9]){4}\b)', '59-59-59-57').groups()) not work?
@barry_allen You require 4 hyphens in the match, and your string has only 3. You also require the match to be at the start of the string and there is no hyphen there
@Potato Thanks for pointing this out and I have fixed it. My brain is now fried like a French fry!
3

In your pattern, this part -{1,4} matches 1-4 times a hyphen so 59-- will match.

If all the matches should be the same as 59, you could use a backreference to the first capturing group and repeat that 3 times with a prepended hyphen.

\b([0-5][0-9])(?:-\1){3}\b

Your code might look like:

import re
res = re.match(r'\b([0-5][0-9])(?:-\1){3}\b', '59-59-59-59')
if res:
    print(res.group())

If there should not be partial matches, you could use an anchors to assert the ^ start and the end $ of the string:

^([0-5][0-9])(?:-\1){3}$

7 Comments

Not sure the OP wants this (the question is unclear), but this is a good answer nonetheless.
This will also match 59-59-59-59 in the string 59-59-59-59-59
@Potato The is why I added If there should not be partial matches, you could use an anchors to assert the ^ start and the end $ of the string.
print(re.match(r'(\b([0-5][0-9])(?:-\1){3}\b)', '59-59-59-59').groups()) fails -> raise error, v # invalid expression sre_constants.error: cannot refer to open group
@Thefourthbird Apologies. I missed that part.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.