Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python regex for line of digits and optional dash+digits. Why not matching?

Tags:

python

regex

I have been struggling with this for an embarrassingly long time so I have come here for help.

I want to match all strings that have a number followed by an optional dash followed by more numbers.

Example:

#Match
1
34-1
2-5-2
15-2-3-309-1

# Don't match
1--
--
#$@%^#$@#
dafadf
10-asdf-1
-12-1-

I started with this regex (one or more digits, followed optionally by a dash and one and more digits):

\d+(-\d+)*

That didn't work. Then I tried parenthesizing around the \d:

(\d)+(-(\d)+)*

That didn't work either. Can anybody help me out?

like image 703
noblerare Avatar asked Feb 24 '14 16:02

noblerare


2 Answers

You can use:

^(\d+(?:$|(?:-\d+)+))

See it work here.

Or, Debugex version of the same regex:

^(\d+(?:$|(?:-\d+)+))

Regular expression visualization

Debuggex Demo

Perhaps even a better alternative since it is anchored on both ends:

^(\d+(?:-\d+)*)$

Regular expression visualization

Debuggex Demo

Make sure that you use the right flags and re method:

import re

tgt='''
#Match
1
34-1
2-5-2
15-2-3-309-1

# Don't match
1--
--
#$@%^#$@#
dafadf
10-asdf-1
-12-1-
'''

print re.findall(r'^(\d+(?:-\d+)*)$', tgt, re.M)
# ['1', '34-1', '2-5-2', '15-2-3-309-1']
like image 139
dawg Avatar answered Nov 14 '22 23:11

dawg


Here's a regex I constructed that covers all your positive test cases; the ruleset is python:

^(?=\d)([-\d]+)*(?<=\d)$

Regular expression visualization

Debuggex Demo

Basically, there's a lookahead to make sure it starts with a number at the start. There's a lookbehind to make sure it ends with a number, too, and each capturing group inbetween is consisting strictly of digits and hyphens.

like image 23
hexparrot Avatar answered Nov 14 '22 23:11

hexparrot