0

I want to make validation for numbers with scientific notation ('e', '+', '-', '.') using regex i tried some of but that's not working like

Regular Numbers

/^(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i

Whole positive and negative number regex validation, supports numbers like -6e4, -16e-10, -0e0 but also regular numbers like -0, -11, and all the entire positive numbers above:

/^-?(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i
const NumberField = (props) => {
  const { errorMessege, ...restProps } = props;

  const Number = /^-?(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i;
  const numberConvertor = (e) => {
    if (e.target.value == '' || Number.test(e.target.value)) {
      // this.setState({and_: e.target.value})}
      console.log(e.target.value);
    } else {
      e.preventDefault();
      // return false;
    }
  };

  return (
    <TextField
      fullWidth
      onKeyPress={numberConvertor}
      helperText={errorMessege}
      error={Boolean(errorMessege)}
      {...restProps}
    />
  );
};
yeti
  • 13
  • 4
  • Does this answer your question? [Parsing scientific notation sensibly?](https://stackoverflow.com/questions/638565/parsing-scientific-notation-sensibly) – Konrad May 29 '23 at 13:03
  • 1
    You are testing one character instead of the whole string – Konrad May 29 '23 at 13:04
  • yes i tried this but not working – yeti May 29 '23 at 13:06
  • 1
    `let regex = new RegExp(Number)` should just be `let regex = Number;`. There is no need to create a new regex instance. – Pointy May 29 '23 at 13:10
  • const Number = /[-+]?[0-9]*\.?[0-9]+([eE][-+]?[0-9]+)?/; const numberConvertor = (e) => { if (e.target.value == '' || Number.test(e.target.value)) { // this.setState({and_: e.target.value})} console.log(e); } else { e.preventDefault(); // return false; } }; – yeti May 29 '23 at 13:31
  • @Pointy I tried this but by using this I am able to type any single char of the string in start – yeti May 29 '23 at 13:32
  • @yeti I don't know what that means. Really it does not make sense to check on every single typed character, because until the user has typed the whole number you cannot tell if the overall input value is valid. When the user first focuses on the field and types `-`, that is not a valid number. However, if the user then presses `2` and tabs to the next field, the value is valid. – Pointy May 29 '23 at 13:44
  • Another thing to think about is that [the "keypress" event is deprecated](https://developer.mozilla.org/en-US/docs/Web/API/Element/keypress_event). Personally I would use the "input" event instead, because that will also handle the case of a user pasting some copied text into the field. (That's if you really want to verify on every change to the value.) – Pointy May 29 '23 at 13:47
  • mean in the textField for first character if I type w or any keyword char it's taking only for first letter – yeti May 29 '23 at 13:48
  • can you have any one example for input event – yeti May 29 '23 at 13:49
  • 1
    Just substitute "input" for "keypress". The "input" event happens when the value of the `` changes for any reason (including keyboard events), and the value of the element in the event handler will be the whole value so far, including the result of processing the keyboard action. – Pointy May 29 '23 at 13:53
  • Just substitute "input" for "keypress". mean ??? – yeti May 29 '23 at 13:59
  • May be helpful if you still want to use `keypress` instead of `input` https://stackoverflow.com/questions/22483214/regex-check-if-input-still-has-chances-to-become-matching – Konrad May 29 '23 at 14:41

2 Answers2

0

/^-?\d+(?:\.\d+)?(?:[eE][+\-]?\d+)?$/ This would work I think

Ajmal Ansari
  • 986
  • 7
  • 8
  • It will not work in the original code posted because the code is wrong apart from the regular expression. Also `[eE]` is unnecessary because the original code had the "i" flag on the expression. – Pointy May 29 '23 at 13:22
0

You could do it in different ways.

  1. Change the input type, like this
const NumberField = (props) => {

  return (
    <TextField
        // your props here
        className="numericInput"
        type="number"
    />
  );
};

This will accept "e" character too, so you can use exponential. Also you can remove the ugly number selector (the arrows next to the input) in css like this:

.numericInput::-webkit-inner-spin-button {
   display: none;
}

.numericInput::-webkit-outer-spin-button {
   display: none;
}

Important If you haven't already, you can use css styling with MUI wrapping your App component inside of styled engine, like this:

<StyledEngineProvider injectFirst>
   <App />
</StyledEngine>

learn more here https://mui.com/material-ui/guides/interoperability/#css-injection-order

  1. You can create a function that deletes every character that is not accepted, like this:
const NumberField = (props) => {
  const { errorMessege, ...restProps } = props;
  const { value, setValue } = React.useState();

  const numberRegex = /yourregex/gi;

  const numberConvertor = (e) => {
    const newValue = e.target.value;
    setValue(newValue.replace(numberRegex, ""));
  };

  return (
    <TextField
      fullWidth
      onChange={numberConvertor}
      helperText={errorMessege}
      error={Boolean(errorMessege)}
      {...restProps}
    />
  );
};

Let me know if any doubt :)

Alexxino
  • 557
  • 2
  • 16
  • in this way this will accept only e char also this is an issue I am facing only e is not valid for the number – yeti May 29 '23 at 14:11
  • if the user put only e then I want to throw an error but by using type=number I am not ale to do it – yeti May 29 '23 at 14:13
  • @yeti you could try to manage the single cases with small reg expressions, like /^e+$/ that only accepts strings that have only "e" characters, or throw an error when input is submitted but is not a valid number – Alexxino May 29 '23 at 18:07
  • no, it will not work I check it's accepting e but for my case, I need to throw an error if only e is put by the user because it's not a valid number. – yeti May 30 '23 at 05:44
  • const Number = /^-?(0|[1-9]\d*)(e-?(0|[1-9]\d*))?$/i; const numberConvertor = (e) => { if (e.target.value == '' || Number.test(e.target.value)) { // this.setState({and_: e.target.value})} console.log(e.target.value); } else { e.preventDefault(); // return false; } }; – yeti May 30 '23 at 08:50
  • I tried this but this is not working properly for example if I put 1e then after it I am not able to type anything – yeti May 30 '23 at 08:52