Domanda

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?

È stato utile?

Soluzione

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.

Altri suggerimenti

You can just use [^0-9] at the beginning and the end and then get the number by looking at the appropriate captured group ( second in this case ):

(^|[^0-9])(0?[1-9]|[1-2][0-9]|3[0-6])($|[^0-9])
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top