Jeya Suriya Muthumari
Jeya Suriya Muthumari

Reputation: 2021

Javascript: Regex to exclude whitespace and special characters

I need a regex to validate,

  1. Should be of length 18
  2. First 5 characters should be either (xyz34|xyz12)
  3. Remaining 13 characters should be alphanumeric only letters and numbers, no whitespace or special characters is allowed.

I have a pattern like here, '/^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13}/g'

But this is allowing whitespace and special characters like ($,% and etc) which is violating the rule #3.

Any suggestion to exclude this whitespace and special characters and to strictly check that it must be letters and numbers?

Upvotes: 1

Views: 1257

Answers (3)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 626758

You should not quantify lookarounds. They are non-consuming patterns, i.e. the consecutive positive lookaheads check the presence of their patterns but do not advance the regex index, they check the text at the same position. It makes no sense repeating them 13 times. ^(xyz34|xyz12)((?=.*[a-zA-Z])(?=.*[0-9])){13} is equal to ^(xyz34|xyz12)(?=.*[a-zA-Z])(?=.*[0-9]), and means the string can start with xyz34 or xyz12 and then should have at least 1 letter and at least 1 digits.

You may consider fixing the issue by using a consuming pattern like this:

  • If you do not care if the last 13 chars contain only digits or only letters, use the patterns suggested by other users, like /^(?:xyz34|xyz12)[a-zA-Z\d]{13}$/ or /^xyz(?:34|12)[a-zA-Z0-9]{13}$/
  • If there must be at least 1 digit and at least 1 letter among those 13 alphanumeric chars, use /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/.

See the regex demo #1 and the regex demo #2.

NOTE: these are regex literals, do not use them inside single- or double quotes!

Details

  • ^ - start of string
  • xyz - a common prefix
  • (?:34|12) - a non-capturing group matching 34 or 12
  • (?=[a-zA-Z]*\d) - there must be at least 1 digit after any 0+ letters to the right of the current location
  • (?=\d*[a-zA-Z]) - there must be at least 1 letter after any 0+ digtis to the right of the current location
  • [a-zA-Z\d]{13} - 13 letters or digits
  • $ - end of string.

JS demo:

var strs = ['xyz34abcdefghijkl1','xyz341bcdefghijklm','xyz34abcdefghijklm','xyz341234567890123','xyz14a234567890123'];
var rx = /^xyz(?:34|12)(?=[a-zA-Z]*\d)(?=\d*[a-zA-Z])[a-zA-Z\d]{13}$/;
for (var s of strs) {
  console.log(s, "=>", rx.test(s));
}

Upvotes: 1

Raj Vaibhav Dubey
Raj Vaibhav Dubey

Reputation: 78

/^(xyz34|xyz12)[a-zA-Z0-9]{13}$/

This should work,

  • ^ asserts position at the start of a line
  • 1st Capturing Group (xyz34|xyz12)
    • 1st Alternative xyz34 matches the characters xyz34 literally (case sensitive)
    • 2nd Alternative xyz12 matches the characters xyz12 literally (case sensitive)
  • Match a single character present in the list below [a-zA-Z0-9]{13}
  • {13} Quantifier — Matches exactly 13 times

Upvotes: 1

Shub
Shub

Reputation: 2704

.* will match any string, for your requirment you can use this:

/^xyz(34|12)[a-zA-Z0-9]{13}$/g

regex fiddle

Upvotes: 1

Related Questions