0

I try to build a custom RegExp pattern for allowing only numbers on input, besides if some letters were inputted after these numbers it should allow them. BUT not only in case if no numbers were inputted before letters.

So I make a tiny regexp, but it even allows k and m letters on input without any numbers on the beginning. That's bad...

Can someone tell me where am I wrong?

Example:

const matchPattern = new RegExp(/[^0-9(k|m)?]$/, 'gi')

'2323'.match(matchPattern) - // true
'23234k'.match(matchPattern) - // true
'23234m'.match(matchPattern) - // true
'k'.match(matchPattern) - // true, BUT should be false
'm'.match(matchPattern) - // true, BUT should be false
Max Travis
  • 1,228
  • 4
  • 18
  • 41
  • This `[^` means a negated character class. Your pattern matches any single char except `0-9`, `(`, `k`, `|`, `m`, `)`, or `?` at the end of the string `$` You could try `^\d+[km]?$` https://regex101.com/r/LJ9KsZ/1/ – The fourth bird Jan 20 '20 at 22:59
  • Hi @Thefourthbird . unfortunately it not working as expected ( ... The same thing the leading k|m is allowed here. – Max Travis Jan 20 '20 at 23:03
  • Can you add the code that you are using to the question? The pattern does not allow a leading `k`. Did you check the regex link? – The fourth bird Jan 20 '20 at 23:04
  • @Thefourthbird I've updated my question. So yeah, thanks your pattern is right, besides I'm looking only for negated one :( .... – Max Travis Jan 20 '20 at 23:06
  • I am curious, why do you want to use a negated pattern? – The fourth bird Jan 20 '20 at 23:14
  • @Thefourthbird "I think you don't mean like this" - I really need it as negated! Well, the current system where I need a regexp pattern can process only with negated one... That's a pity, yeah. – Max Travis Jan 20 '20 at 23:19
  • If you want only numbers first and then optionally a letter, you could try 2 negated character classes `^[^\D]+[^\W\d_a-jln-z]?$` https://regex101.com/r/10Gd4f/1 – The fourth bird Jan 20 '20 at 23:38
  • @Thefourthbird thanks a lot for your advice! Nevertheless, any symbol classes won't let you work within `new RegExp` negated literal, i.e. `var a = '\d'; // new RegExp(a); === new RegExp('d');`, not as `\d`. – Max Travis Jan 21 '20 at 08:13
  • 1
    You have to double escape the backslash. – The fourth bird Jan 21 '20 at 08:22
  • @Thefourthbird wow! Thanks a lot! Make your question as an answer and I'll voute it up! – Max Travis Jan 21 '20 at 10:57
  • I have added it as an answer with an explanation. – The fourth bird Jan 21 '20 at 12:26

1 Answers1

1

If you can use a negated character class only, you might use:

^[^\D]+[^\W\d_a-jln-z]?$

Regex demo

  • ^ Start of string
  • [^\D]+ Match 1+ times any char except not a digit (match a digit)
  • [^\W\d_a-jln-z]? Optionally match any char except not a word char, digit, _ or a-z range except k and m
  • $ End of string

const matchPattern = new RegExp("^[^\\D]+[^\\W\\d_a-jln-z]?$", "i");
console.log('2323'.match(matchPattern));
console.log('23234k'.match(matchPattern));
console.log('23234m'.match(matchPattern));
console.log('k'.match(matchPattern));
console.log('m'.match(matchPattern));
The fourth bird
  • 154,723
  • 16
  • 55
  • 70