0

I have a regEx for checking a number is less than 15 significant figures, Borrowed from this SO answer

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

The the other is used to check that same number is upto 2 decimal places(truncate)

  1. /^-?(\d*\.?\d{0,2}).*/

I have almost 0 regex skill.

Question: How do I combine the 2 regexes to do the work of both, AND not just either OR( accomplished by | character - i am not sure if it achieves same function as combining both)

something like:

/^-?(?=\d{1,15}(?:[.,]0+)?0*$|(?:(?=.{1,16}0*$)(?:\d+[.,]\d+)‌​)).+$ <AND&&NOTOR>(\d*\.?\d{0,2}).*/

Thanks in advance

EDIT: edit moved to a seperate SO question

Fatah
  • 2,184
  • 4
  • 18
  • 39
  • 3
    Possible duplicate of [Regular Expressions: Is there an AND operator?](https://stackoverflow.com/questions/469913/regular-expressions-is-there-an-and-operator) – L3viathan Apr 17 '18 at 12:18
  • 1
    What the result you want to get? – Salim Ibrohimi Apr 17 '18 at 12:42
  • .. Basically given any whole number, it should not exceed 15 significant digits. Given any decimal, it should not exceed 2 decimal points. – Fatah Apr 17 '18 at 14:07
  • I'm updating my answer to address your updated need. Careful when asking for a regex to be clear whether you want to check that data respects a pattern or use it to extract data (your 15-digit/2-floating digit number) from larger data (the whole number), the needed regex aren't similar – Aaron Apr 17 '18 at 14:25
  • @Aaron if they are not similar, they shouldnt be combined? is it recommended to just chain the replace function for each regex? – Fatah Apr 17 '18 at 14:48
  • I meant that a regex for checking won't be the same as a regex for extracting/replacing. For instance, the linked question, Thm Lee's answer and mine all were enclosed between `^`anchors`$` that would make the match fail if the number contained more than the specified number of digits. But you can't use that for extracting the desired number of significant digits, because they won't always be found at the start or end of the string but in the middle. It's still possible to craft a single regex for your use case (although I'm currently struggling to make sure it prioritize the integer part) – Aaron Apr 17 '18 at 14:56
  • BTW, what should `1234567890123456789` be replaced by? `1234567890123450000`? Because while we've been stretching the use of regexs for a while now, it *really* wouldn't be appropriate for this – Aaron Apr 17 '18 at 15:06
  • @fatahn Check [this regex101](https://regex101.com/r/tE40zM/3) out ; not too bad, but not perfect either (doesn't match `0.x` because the single 0 isn't considered significant, and won't replace insignificant integer digits by 0 as mentionned above). I might solve the `0.x` problem later, in which case I'll post the regex as a solution. I won't fix the insignificant integer digits replacement by 0s though, this isn't something that should be handled by regex – Aaron Apr 17 '18 at 15:42
  • Thanks alot for your effort @Aaron. What I dont understand is why doesn't the regex replace my input inside that fucntion. I tried it even in th browser console and it does not work. For example `format1(0.1234567890,/^-?(\d*\.?\d{0,2}).*/)` correctly returns `0.12`. Or should I open a new question for this? Thanks – Fatah Apr 18 '18 at 07:50
  • @Aaron I put up [a new question](https://stackoverflow.com/questions/49894174/why-doesnt-my-function-correctly-replace-when-using-some-regex-pattern?noredirect=1#comment86806235_49894174) i think that would be more appropriate – Fatah Apr 18 '18 at 10:38
  • @fatahn hey, I wasn't available yesterday, sorry about that. It looks like your other question already has got quite the attention, are you still stuck on your problem? – Aaron Apr 19 '18 at 08:53
  • hey @Aaron, no worries. I quite understand how it works, yet still stuck on getting the regext t work within a function – Fatah Apr 19 '18 at 09:04
  • Do you really have to use regex btw? I think arithmetic operations would make the whole thing easier – Aaron Apr 19 '18 at 09:06
  • I think so because `toFixed()` and `toPrecision` round up the number. But you are right maybe i dont have to. I'll continue to try out those solutions on the side. Thanks – Fatah Apr 19 '18 at 09:11
  • I'll look into it too, although I'm not sure when I'll be able to come up with an answer. BTW I'm still unclear on what output you expect for numbers with more than 15 significant digits in the integer part, e.g. 1234567890123456789. 1234567890123450000 ? – Aaron Apr 19 '18 at 09:20
  • Thanks a lot @Aaron. Actually everything should be restricted to less than 16 Sgn. digits. [according to this definition of sign figs](https://en.wikipedia.org/wiki/Significant_figures)... Basically whatever the input(integer or decimal part) i expected that input to be replaced with the first 15 sifgnificant figures WHICH also is restricted to 2 decimal places. so `123456789012.3456 ` would be 123456789012.34` (instead of `123456789012.345` - which has 15 sig fig ). – Fatah Apr 19 '18 at 09:34
  • `Math.floor(n*100)/100` is enough for that case, but it leaves integers parts with more than 15 significant digits untouched, and will round floats with no significant digits before the 3rd floating digit to 0, I don't know if it's ok for you – Aaron Apr 19 '18 at 09:43
  • this wont help because i am using [`bignumber.js`](https://mikemcl.github.io/bignumber.js/#Errors) for my other calculations. I have to restrict user input, thats why, thanks though – Fatah Apr 19 '18 at 09:46

1 Answers1

1

If you add only one condition of maximum 2 decimal places to first regex, try this..

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

Demo,,, in which I only changed original \d+ to d{1,2}$

Edited for the reguest to extract 15 significant figures and capture group 1 ($1). Try this which is wrapped to capture group 1 ($1) and limited 15 significant figures to be extracted easily.

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

Demo,,, in which changed to .{1,16} from .+$. If the number matches, then able to be replaced $1, but if not so, replaced nothing, thus remains original unmatched number.

Therefore, if you want to extract 15 significant figures by replacing with $1 only when your condition is satisfied, try this regex to your function.

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

Demo,,, in which all numbers are matched, but only the numbers satisfying your condition are captured to $1 in format of 15 significant figures.

Thm Lee
  • 1,236
  • 1
  • 9
  • 12
  • Thanks. I made a function to see if i can correctly replace but your regex and others work elsewhere but not within my function( `const format1 = (number, regex) => String(number).replace(regex, '$1')`)... Basically given any whole number, it should not exceed 15 significant digits. Given any decimal, it should not exceed 2 decimal points. – Fatah Apr 17 '18 at 14:01
  • Didn't you set `multiline flag` `m` in your regex function? I suspect it in this time. – Thm Lee Apr 17 '18 at 14:07
  • I think it's the reference to a `$1` capturing group in the replace that is problematic. Both Thm Lee's and my regex were made to validate, not to extract (they're anchored) ; they define no such capturing group, and if they did the replace would be a no-op. – Aaron Apr 17 '18 at 14:15
  • like this `/.../m` ? – Fatah Apr 17 '18 at 14:18
  • @Aaron, Yes, it is.. fatahn's function refers wrongly to `$1` because the regex has not any capture group. Therefore recommend fatahn to use `$0` instead of `$1` – Thm Lee Apr 17 '18 at 14:20
  • Otherwise, use `$1` after wrapping the regex with parenthesis. – Thm Lee Apr 17 '18 at 14:27