-2

I need some help with Regular Expression, the problem is that I need apply the regex with Replace method in JavaScript. I saw a few post here in Stackoverflow but any regex doesn't works, I don't why.

I need that the user only can type in the input the following data:

100
100.2
100.23

Note: only number, it could be with one or two decimals maximum. Don't allow another symbols, and of course one comma.

I have been reading about it, and I used a few regex generator to see the match, so I made this one:

/^[a-zA-Z]+(\.[a-zA-Z]{0,2})?$/

I got a little bit confused at the beginning because I used in the replace method:

elementOne.addEventListener("input", function(event) {
   this.value = this.value.replace(/^[a-zA-Z]+(\.[a-zA-Z]{0,2})?$/, '');
});

And right now I read the process like: if I type a letter from a to z,the method will replace to space ''. but the rest doesn't works in the method but works in the generator for example.

Here is an example, you will see in the first input my regex vs Sven.hig regex:

const elementOne = document.getElementById('elementOne');
const elementTwo = document.getElementById('elementTwo');

elementOne.addEventListener("input", function(event) {
   this.value = this.value.replace(/^[a-zA-Z]+(\.[a-zA-Z]{0,2})?$/, '');
});

elementTwo.addEventListener("input", function(event) {
   this.value = this.value.replace(/^\d+[,]?\d{0,2}/, '');
});
<p>Element One (My RegEx)</p>
<input id="elementOne" type="text" />
<p>Element Two (Stack RegEx)</p>
<input id="elementTwo" type="text" />

Also as a CodePen

yasserpulido
  • 198
  • 1
  • 2
  • 11
  • 3
    It's not clear to me what you're trying to do. Your sample data is numerals followed by an optional decimal part, but your regex says "replace 1-to-many alphabetical letters followed by an optional dot and 0-2 alphabetical letters with an empty string." What exactly are you trying to do? – Jacob Jul 16 '20 at 00:13
  • Did you by mistake use a dot `.` instead of a comma `,`? And do you want to match letters or numbers? – ssc-hrep3 Jul 16 '20 at 00:15
  • @ssc-hrep3 I used dot because the post, I know that in latin America we use comma. But could be the same. – yasserpulido Jul 16 '20 at 00:29
  • @Jacob This is the reading of the replace process that I'am understanding right now: if I try to type a letter [a-zA-Z]+, I will receive empty space. But if I type a number, I will be allowed, but the rest of the regex doesn't works. What exactly am I trying to do? An input that only allow type a number with decimals. – yasserpulido Jul 16 '20 at 00:29
  • I think your question is unclear — I _**do**_ see why the letters, not numbers, because you are trying to _eliminate_ the letters (regex is replacing them with empty string `''`) but you don't show any context for this. Is your `this.value = this.value.replace(...)` getting called in response to a keyboard event, or an onchange event, or something similar? I think you'll have to show a bit more code (and markup) to provide enough context for a good answer. See [mcve] – Stephen P Jul 16 '20 at 00:35
  • @StephenP I added a CodePen with two example, the first input is with my regex and the second one is from Sven.hig answer below here in my post answer. – yasserpulido Jul 16 '20 at 00:42
  • 1
    You may want to see https://stackoverflow.com/questions/8282266/ and https://stackoverflow.com/questions/13607278/ about how to restrict the input. Or you could use an `` which allows decimals (but not group separators) and the decimal character it allows _should_ be based on Locale. As a bonus `type="number"` will generally switch to a numeric keyboard on mobile devices. – Stephen P Jul 16 '20 at 00:48
  • it looks like you want to prevent users from enter words but only numbers and an optional `,` that's not what your question implies you said you want a pattern to detect numbers – Sven.hig Jul 16 '20 at 00:50
  • @sven.hig I saw a post here in stackoverflow that only allow type number in a input (https://stackoverflow.com/a/19111723/13029578). So, I tried to do the same but with decimals. I think that I was clear with this line "I need that the user only can type in the input the following data:..." – yasserpulido Jul 16 '20 at 01:17
  • I have updated my answer with code snippet check it out – Sven.hig Jul 16 '20 at 01:22

2 Answers2

1

Your regex is to match words not numbers you should replace [a-zA-Z]by [0-9] and the \. by \,

so your regex should look like this /^[0-9]+(\,[0-9]{0,2})?/

alternatively you could shorten the pattern /^\d+[,]?\d{0,2}/gm

here is code snippet to prevent user from entering words or any number that doesn't match the pattern

const elementTwo = document.getElementById('elementTwo');
var flag=false
elementTwo.addEventListener("input", function(event) {
  pattern=/^\d+[,]?\d{0,2}$/
   if (pattern.test(this.value)){
         flag=true
         l=this.value
         if(flag&&this.value.length>1)
          return this.value
          else flag=false 
        
   }
  else if(!pattern.test(this.value)&&flag==true){
         return this.value=l
  
     }
       
     else if(!pattern.test(this.value)&&flag==false){
         return this.value=""
  
     }
       
});
<p>Element Two (Stack RegEx)</p>
<input id="elementTwo" type="text" />
Sven.hig
  • 4,449
  • 2
  • 8
  • 18
  • I tried something like that, and I can type letter. I tried now with your regex, and I can type letter. That is why I do the opposite, and you think that I'm wrong. Maybe could be the event or something like that I'm doing wrong. I will edit my post and add a CodePen with two input, my regex and your regex. Follow me! – yasserpulido Jul 16 '20 at 00:37
  • I have updated my answer and included a code snippet check it out – Sven.hig Jul 16 '20 at 01:21
  • That I have trying to do, I didn´t know about test method. But, Is it a way to just prevent type letters and just not delete everyting when you type a letter for example? – yasserpulido Jul 16 '20 at 01:50
  • can you give me an example? – Sven.hig Jul 16 '20 at 01:51
  • A example could be:1).Run your code snippet. 2).typedown 22 3).And then type a letter, everything is deleted in the input. I am burnout to think, I spent the entire day in this. Sorry and thanks in advance. PD: I was thinking about maybe do not return a empty space, if not return the last value typed, what do you think? @Sven.hig – yasserpulido Jul 16 '20 at 02:04
  • That was awesome, man!, that I was trying to do. Also, make me learn about others regex method. Thanks a lot! – yasserpulido Jul 16 '20 at 04:14
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/217965/discussion-between-yasserpulido-and-sven-hig). – yasserpulido Jul 16 '20 at 12:45
0

It looks like you're confusing a few things:

  • Replacing invalid characters in a string
  • Defining a validation pattern
  • Preventing entry of text

If your goal is to validate that your string has the correct format, you'd define a regular expression like:

const validFormat = /^\d+(,\d{0,2})?$/;
console.log(validFormat.test('99'));        // true
console.log(validFormat.test('100,23'));    // true
console.log(validFormat.test('X00,2E'));    // false
console.log(validFormat.test('%#&SJ&#UJ')); // false

If your goal is to remove invalid characters (non-digits, non commas), you can define a regular expression for those invalid characters, but that's not the same thing as making sure your string now has a valid format. RegExp isn't able to do anything like that:

const invalidChars = /[^\d,]/g;
const sanitized = someString.replace(invalidChars, '');

If you want to prevent typing characters, you're better off adding a keydown event handler to your input and prevent the default behavior for invalid keys.

const myInput = document.querySelector('#some-input');
myInput.addEventListener('keydown', ({ key, preventDefault }) => {
  if (key !== ',' && (key < '0' || key > '9')) {
    preventDefault();
  }
});
Jacob
  • 77,566
  • 24
  • 149
  • 228
  • I'd definitely go with @StephenP's suggestion to use a numeric input, though; leaving this here in case it's still useful to you or others. – Jacob Jul 16 '20 at 00:52