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?
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.