0

In my current app, I am implementing field validation with regex for forms.

More specifically, I am having trouble handling edge-case for numbers with decimals.

Essentially I am using regex to prevent users from typing wrong information in to the input fields.

For instance, if user would type 12.2 and then . afterwards, I am using regex to detect what shouldn't be there, and replace with empty string, ''

Here's my current implementation using a call back function:

export const checkFormat = (typeFormat, value) => {
  //value is stringified
  switch (typeFormat) {
    //...
    case NUMERIC_DECIMALS: {
      return value.replace(/(\d+\.\d+)(\.*)\d*/g, '$1')
    }
  }

}

However, the current regex implementation can't handle such cases as

  • User types : ., then .. ==> .
  • User types : 123.2, then 1.23.2 ==> 1.232

I'm fairly new to Regex, so obviously it needs some work

5
  • 2
    just don't replace on the fly, it is annoing Commented Jun 29, 2017 at 5:59
  • 1
    Question is a bit unclear. Could you please elaborate some more on the input and expected output? Commented Jun 29, 2017 at 6:00
  • Could you give the list of valid and invalid inputs and expected output? Commented Jun 29, 2017 at 6:01
  • for these three input: a) 1.2 b)1.23 c)1.2.3.4 the output should be : a)1.2 b)1.23 c) 1.2 is that correct ? Commented Jun 29, 2017 at 6:02
  • if you only want decimal, why not replace every non-digit char after first dot? so, 1.00sdsdsd = 1.00 Commented Jun 29, 2017 at 6:14

3 Answers 3

1

You can try this:

^(\d+(?:\.\d+)).*$

and replace by this:

$1

Regex 101 demo

Or to get the a more complex solution, which I guess you are looking for, you may try this:

const regex = /^(\d+(?:\.\d*))|(\.)?/gm;
const str = ["1.2","...","g..g","1.23","1.2.3.4",".,",".,","123.2","1.23.2","14","1","15.6.4789756465","g"];
const replaceRegex = /[^\.\d]/gm;
for(var i=0;i<str.length;i++)
{
var res=str[i].replace(replaceRegex,'').split(regex);
var finalResult="";
var alreadyContainsDot=false;
for(var j=0;j<res.length;j++)
  if(res[j]!=null && res[j]!="")
  {
    if(res[j].includes(".") && !alreadyContainsDot)
      alreadyContainsDot=true;
    else if(res[j].includes(".") && alreadyContainsDot)
      res[j]=res[j].replace(/\./gm,'');
    finalResult+=res[j];
  }
console.log(str[i]+"==>"+finalResult);
}

Sign up to request clarification or add additional context in comments.

Comments

1

If my interpretation of the requirement is correct, this should work:

const regex = /(\d+\.?\d+?)(\D+)/g;
const str = `131/1.13.ad`;
const subst = `$1`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

Regex101 link

Comments

0

It is bad UX practice to monitor what the user is typing and change his input out from underneath him. He is likely to think his keyboard is broken. I don't know when or how this approach became so widespread, but thankfully it seems to be dying out.

In any case, it is always a bad idea to try to do things with numbers using regexps, which are fundamentally designed for manipulating strings. If for some reason you need to check if some string is a valid number, use numeric APIs such as !isNaN(+value).

Use the appropriate type or pattern attributes on your input fields to do validation. If that does not suffice, validate when the user presses the "Submit" button or equivalent.

1 Comment

I completely agree with you. However, my client insistently wants this feature, which I've opposed from the beginning but they've decided to have it anyway :/

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.