Search code examples
regexregex-lookaroundslookbehinddigit

Regex - Match number range with no numbers around it


So I have something like this:

\b(0?[1-9]|[1-2][0-9]|3[0-6])\b

Which works fine for only matching numbers 1-36. But I might get something like S36, which won't get matched. I can't assume a clean word boundary on either side of the number.

I'd like to have it so it'll match 1-36 with anything except other numbers on either side.

I thought something like this would work, but it doesn't:

(?<=\D)(0?[1-9]|[1-2][0-9]|3[0-6])(?=\D)

It's supposed to be a positive look-behind at the start to make sure there is anything but digits preceding the number and a positive look-ahead after the number to make sure the same is true following it.

What is the correct way of doing this?


Solution

  • If your engine doesn't support lookbehind/lookahead, then you can still just match the whole thing including the non-digits and pick the capture you're interested in.

    (?:^|[^1-9])(0?[1-9]|[1-2][0-9]|3[0-6])(?:$|[^1-9])
    

    Your result would be in capture 1 in this example (the "outer" matches are in non-capturing groups).

    Note that with .NET, you do have full support for lookbehind and lookahead, so that the following should work:

    (?<![0-9])(?:0?[1-9]|[1-2][0-9]|3[0-6])(?![0-9])
    

    This uses negative lookaround instead of positive lookaround. Otherwise, numbers that are at the beginning or end of the string will not match because a non-numeric character is required where there is no character, leading to a non-match.