Question

I think it's called a negative look-ahead /x(?!y)/, but I'm not sure since I just started doing regex stuff today. I'm trying to validate the following:

  // Matches aa-00 through ZZ-99
  var regex = /([a-zA-Z]{2}(?!\b))((-){1})([0-9]{2}(?!\B))/;

  var result = regex.test("EV-05"); // Should pass
  Console.log("EV-05: " + result + "\n");

  result = regex.test("ev-09"); // Should pass
  Console.log("ev-09: " + result + "\n");

  result = regex.test("eV-11"); // Should pass
  Console.log("eV-11: " + result + "\n");

  result = regex.test("Ev-30"); // Should pass
  Console.log("Ev-30: " + result + "\n");

  result = regex.test("ev03"); // Should fail
  Console.log("ev03: " + result + "\n");

  result = regex.test("e-17"); // Should fail
  Console.log("e-17: " + result + "\n");

  result = regex.test("ev-5"); // Should fail
  Console.log("ev-5: " + result + "\n");

  result = regex.test("evv-36"); // Should fail
  Console.log("evv-36: " + result + "\n");

  result = regex.test("ev-019"); // Should fail
  Console.log("ev-019: " + result + "\n");

  result = regex.test("ev--05"); // Should fail
  Console.log("ev--05: " + result + "\n");

Here's what I want:

LETTER#LETTER#HYPHEN#DIGIT#DIGIT (honestly have no idea how to describe that in a readable fashion).

I do not want to allow input of extra values for any of those 5 parameters. It must be exactly 2 letters followed by a hyphen, followed by 2 digits (0-9). I want to validate that there are not 3+ letters, nor 3+ digits.

I thought that the {n} occurrence marker for each would be enough, but it still returns true when there are 3+ letters/digits (as is the intention of the {n} marker). Thus I tried the negative look-ahead to return false if another word \b was found for the letters, and non-word \B for the digits. But that didn't work either.

If I remove the negative look-aheads and the \b & \B and just stick with the original:

var regex = /[a-zA-Z]{2}(-){1}[0-9]{2}/;

Then half of the values are valid, but the ones with extra characters/digits are also considered valid.

Long story short: How do I ensure that there are exactly X amount of occurrences something, and return false when there are extra? Maybe I'm just messing up the NLA implementation.

Was it helpful?

Solution

You're making things a little more complicated than they should be here. You can use something like this:

/^[a-zA-Z]{2}-[0-9]{2}$/;

^ will match the beginning of the string and $ will match the end of the string.

This regex will allow only strings containing 2 letters, followed by one hyphen and followed by 2 digits. You can rewrite [0-9] as \d as well in javascript.


/([a-zA-Z]{2}(?!\b))((-){1})([0-9]{2}(?!\B))/;

This doesn't quite work as you might expect. (?!\b) prevents a word boundary from occurring immediately after the 2 letters, which will make your valid strings fail.

((-){1}) You don't need so many parenthesis, even if you want to group those, because there's hardly anything to group. Use parentheses to capture stuff you'll use later on. The {1} is redundant as well. I have never seen a single concrete use of {1}. {n} is useful when n is greater than 1.

([0-9]{2}(?!\B)) Again, the parentheses are not quite useful, but here, you used a negated word boundary, which should work well (similar to $ but anywhere in the string).

If you want to match such format anywhere in a string, then you can use word boundaries as follows:

/\b[a-zA-Z]{2}-[0-9]{2}\b/;
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top