0

Looking to match all sums from £1 to £155 with an optional set of pence digits after a full stop, so £59.65 matches, and £0.47 and £155.56 won't match.

Here is what I have so far:

£\d{1,3}([1-9]|[1-9][0-9]|1[0-5][0-5])(?:[,.])?\d{1,2}

Natural Numbers and Decimals between 1 - 155

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
William Rose
  • 47
  • 2
  • 9

2 Answers2

2

If lookaheads are supported with your regex flavour, you can try this:

£(?:1(?:[0-4](?:[0-9]?(?:[.,][0-9]{1,2})?)?|5(?:[0-4](?:[.,][0-9]{1,2})?|5(?:[.,]00?)?)|[6-9]?(?:[.,][0-9]{1,2})?)?|[2-9][0-9]?(?:[.,][0-9]{1,2})?)(?![.,]?[0-9])

demo

Casimir et Hippolyte
  • 88,009
  • 5
  • 94
  • 125
2

What about:

£((\d|[1-9]\d|1[0-4]\d|15[0-4])(\.\d{2})?|155(\.00)?)

The regex works as follows: it always starts with the leading pound sign (£). Next it considers two cases: the one where the value is less than 155 and the one where it is 155. The case of 155 is simple: 155(\.00)?: 155 optionally followed by a dot and two zeros.

The case of less than 155 is more complex: we branch into several cases:

  • the one with one digit \d (zero to nine);
  • the one with two digits, but no leading zeros: [1-9]\d;
  • the one with three digits: but since the result should be less than 155 we again have to branch:
    • the ones less than 150: these start with a 1 followed by a number between 0 and 4 (inclusive) followed by any digit \d, so 1[0-4]\d;
    • the ones greater than or equal to 150, but less than 155, these all start with 15 and are followed by something in the range of 0 to 4 (inclusive), so 15[0-4].

All these are followed optionally by a dot and two digits (\.\d{2}).

This regex reject numbers with leading zeros (like 09.12) except of course if there is one digit: 0.85 is allowed.

I here assumed there are always two digits after the decimal dot(so 0.1 and 14.135 are not allowed), in case an arbitrary amount is allowed, simply replace \.\d{2} with \.\d+ (in case at least one digit is required), or \.\d* if even no digits are allowed.

Willem Van Onsem
  • 443,496
  • 30
  • 428
  • 555
  • And this is downvoted because... Although I agree regexes are not the way to check integer bounds, it can be done as is demonstrated here. – Willem Van Onsem Jan 09 '17 at 19:56
  • Your pattern works well, except it doesn't check cases when there is only one digit after the dot/comma (1.1) or more than two digits (155.001). – Casimir et Hippolyte Jan 09 '17 at 20:13
  • @CasimiretHippolyte: well based on the comment, I think there are exactly two digits allowed (I don't know prices where they show one or three digits, except for gas stations). I agree I don't take these into account, but the pattern can easily be expanded. – Willem Van Onsem Jan 09 '17 at 20:16
  • @CasimiretHippolyte: I've added a little note that one can easily extend the regex pattern. – Willem Van Onsem Jan 09 '17 at 20:17
  • I found this: `£([1-9]{1,2}(\.[0-9]{2})?|1[0-5][0-4](\.[0-9]{2})?|[1-9][0-9]|1[0-4]?[0-9]?|155(?!\.))\b` to work. – Josh Jan 03 '18 at 19:36
  • @Jimmy: this does not match `£155.00`. – Willem Van Onsem Jan 03 '18 at 19:41