tags:

views:

74

answers:

8

Hallo everyone,

I am trying to find a resolution for a regex expression:

I want to have something like this

"string x/0/y" where x is in a range between 1-6 and y is in range between 1-48

I tried this:

interface GigabitEthernet [1-6]/0/([1-4]*[1-8])

but then if y = 50 it still takes 5 under consideration and drops "0"

I tried this

interface GigabitEthernet [1-6]/0/([1-4][1-8])

but then if y = 1-9 it does not match the expression.

I would appreciate any help on this.

Thank you !

+4  A: 

Try ([1-9]|[1-3][0-9]|4[0-8]) for the second part of your regex.

Keep in mind that if you need to do lots of similar searches, regex alone isn't necessarily the best tool for the job. Your program could instead search for the general pattern of /(\d+)/0/(\d+)/, extract the match groups, then validate the numeric ranges.

Jacob
Beat me to it ;-)
Andrew Cooper
You need to add a `$` to the end, since `50` still matches the `[1-9]` alternative.
Adam Rosenfield
Or something at the end, if not the end of the line.
Jacob
Using the .NET or Java regex engine, the cases e.g. `1/0/49` and `1/0/100` have a false-positive with your regex. Additionally, `1/0/39` matches only partially instead of fully. You may want to add an anchoring token at the end of your regex to fix this, such as `$` or `(?!\d)`
Mike Clark
+1  A: 

Try this:

interface GigabitEthernet [1-6]/0/([1-9]|[1-3][0-9]|4[0-8])
Andrew Cooper
Using the .NET or Java regex engine, the cases e.g. `1/0/49` and `1/0/100` have a false-positive with your regex. Additionally, `1/0/39` matches only partially instead of fully. You may want to add an anchoring token at the end of your regex to fix this, such as `$` or `(?!\d)`
Mike Clark
A: 

You need something like this

[1-6]/0/([1-9] | [1-3][0-9] | 4[0-8])

Ben
Using the .NET or Java regex engine, the cases e.g. `1/0/49` and `1/0/100` have a false-positive with your regex. Additionally, `1/0/39` matches only partially instead of fully. You may want to add an anchoring token at the end of your regex to fix this, such as `$` or `(?!\d)`
Mike Clark
Could you explain how 1/0/49 and 1/0/100 are false positives?
Ben
+4  A: 

I don't recommend trying to do numeric range checking within a regular expression. It's hard to write and even harder to read. Instead, use a regular expression like this:

(\d)/0/(\d{1,2})

Then, using the captured groups, check to make sure that the first one is

x >= 1 and x <= 6

and the second one is

y >= 1 and y <= 48

This will be much easier to read later, when you need to come back to it.


A concrete example in Python might be:

s = "5/0/14"
m = re.match(r"(\d)/0/(\d{1,2})", s)
if m is not None:
    x = int(m.group(1))
    y = int(m.group(2))
    if x >= 1 and x <= 6 and y >= 1 and y >= 48 then
        print("Looks good!")
Greg Hewgill
Agreed! People often want to solve 100% of a complex problem using pure regex. Often the sanest, most efficient, maintainable, and readable approach, however, is to use a simple regex, and express the complexities and boundaries in code.
Mike Clark
A: 

GigabitEthernet [1-6]/0/((4[0-8])|([1-3]?\d))

this handles the last part with 2 options. one for everything up to 39 and one for 40-48

Seattle Leonard
The cases e.g. `1/0/49` and `1/0/100` have a false-positive with your regex. You may want to add an anchoring token at the end of your regex to prevent this false positive, such as `$` or `(?!\d)`
Mike Clark
+1  A: 

Regex is not very elegant when it comes to expressing such arbitrary number ranges. Either of these should work though:

interface GigabitEthernet [1-6]/0/([1-3][0-9]|4[0-8]|[1-9])$

or

interface GigabitEthernet [1-6]/0/([1-3][0-9]|4[0-8]|[1-9](?![0-9]))

One or the other might be more or less suited to your regex engine or target data, but only you would know that.

Mike Clark
Brilliant, thanks so much that works perfectly!
Paul
A: 

Thank you very much for all your help guys. The issue is resolved.

Paul
On SO, you're supposed to accept an answer then, not add another "comment disguised as an answer". Could you please select the best response?
MSalters
+1  A: 

Others have suggested ([1-9]|[1-3][0-9]|4[0-8]). It works, but isn't really efficient because the alternatives can only be distinguished past the first character, i.e. this can require backtracking.

The regex ([1-3][0-9]?|4[0-8]?|[5-9]) matches the same strings. However, here the first character uniquely determines which alternative is taken, and no backtracking is required.

MSalters
Using the .NET or Java regex engine, the cases e.g. `1/0/49` and `1/0/100` have a false-positive with your regex. Additionally, `1/0/39` matches only partially instead of fully. You may want to add an anchoring token at the end of your regex to fix this, such as `$` or `(?!\d)`
Mike Clark