0

I would have thought this would be fairly common, but haven't found a solution

What I would like is a regular expression that fails on a set number of significant figures (a Max), but passes for less than the Max. I would like it to work with both dot or comma (french) decimal separators.

So for 15 significant figures, these should pass:
0
0.00
1
-1
1.23456789012345
10.2345678901234
12.3456789012345
-123.4
-12.34
-1,33
-1.33
-123456789012345
-1234567890123450
-12345678901234.50
12345678901234.50
123456789012345.00

// should fail:
-1234567890123456
-12345678901234.56
12345678901234.56
123456789012345.60
1.234567890123456
12.34567890123456
123456789012340.6
123456789012300.67
123456789012300000000000.67
10000000000010000000001000010000000001.22

I know I need to use negative look a heads, and I have got close with this so far:

^(?!(?:.*?[1-9]){15,})([-+]?\s*\d+[\.\,]?\d*?)$

https://regex101.com/r/hQ1rP0/218

but you can see the last few still pass, any pointers?

  • You have conflicts. `-1234567890123450` is 16 digits and valid, while `-1234567890123456` is also 16 digits and fail – ctwheels Oct 19 '17 at 15:33
  • Thats correct, since -1234567890123450 is 16 digits, but ends in a 0, then there are only 15 significant figures relevant to scientific notation. Where as -1234567890123456 has 16 figures relevant to scientific notation – bobbybobbobbed Oct 19 '17 at 15:40
  • `0`s before the decimal are significant. – ctwheels Oct 19 '17 at 15:41
  • `^-?(?=\d{1,15}(?:[.,]0+)?$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))).+$`, with your weird *significant number* logic, however `^-?(?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))).+$` – ctwheels Oct 19 '17 at 15:45
  • Darn, cant update the question. But I want to be able to ignore trailing zeros. Meaning, that I want to count the significant figures, but ignore them if they are terminal zeros. So in my case, ignore 0s before the decimal if there are no non zero decimal numbers, but include them if there are. I'm trying to catch the case when scientific notation inaccurately rounds. – bobbybobbobbed Oct 19 '17 at 15:47
  • @ctwheels. that works very well, seems to catch the examples perfectly. Thank you (would accept as ans if you added it, still testing a few more examples). It's really useful for catching limits of javascript – bobbybobbobbed Oct 19 '17 at 15:59

1 Answers1

2

Code

For actual scientific notation (where leading zeros matter before the decimal symbol), you can use the following

^-?(?=\d{1,15}(?:[.,]0+)?$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+)))‌.+$

This next regex, however, works for your case of leading zeros regardless of decimal position.

See this regex in use here

^-?(?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+)‌​)).+$

Explanation

  • ^ Assert position at the start of the line
  • -? Match zero or one of the - character literally
  • (?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+))) Positive lookahead ensuring what follows matches the following
    • \d{1,15}(?:[.,]0+)?0*$ Option 1
      • \d{1,15} Match between 1 and 15 of any digit character
      • (?:[.,]0+)? Match a decimal symbol ,., followed by one or more 0s literally, but either zero or one time
      • 0* Match any number of 0s literally
      • $ Assert position at the end of the line
    • (?:(?=.{1,16}0*$)(?:\d+[.,]\d+)) Option 2
      • (?=.{1,16}0*$) Ensure what follows matches the following
      • .{1,16} Match any character between 1 and 16 times
      • 0* Match any number of 0s literally
      • $ Assert position at the end of the line
      • (?:\d+[.,]\d+) Match the following
      • \d+ Match any digit between 1 and unlimited times
      • [,.] Match a decimal character
      • \d+ Match a digit between 1 and unlimited times
  • .+ Match any character one or more times
  • $ Assert position at the end of the line (not really needed but I think for readability it helps)
ctwheels
  • 21,901
  • 9
  • 42
  • 77