I've been using a regex for some time with jQuery validation to ensure my users input valid strings for drawing names. In the past week we've added the ability to use 3rd-party devices whose strings are somewhat different. I'm tasked with allowing those strings as well as the previous set as valid input. I send them to this validator adapted from this SO answer:
$.validator.addMethod("accept", function (value, element, param)
{
return value.match(new RegExp("^" + param + "$"));
});
Notice I'm tacking on the ^
& $
characters.
Like this:
drawingName: {
required: true,
accept: "[0-9]{4,5}[\\.?\\w*]{0,4}"
},
The double backslashes escape the single backslashes for use in the validator. If you're testing in something like http://www.rubular.com/, you'll want to use single backslashes.
The previous set (for which I made generic representations, where "X" represents letters, "0" represents digits, and decimal points are what they are) consisted of these valid possibilities:
00000
00000.0
00000.00
00000.X
000000
000000X
00000X
00000X.0
00000X.0X
00000X0.0
00000XX.0
0000X.0
There are tens of thousands of these variants in my data, and changing them is not a possibility. The company is working on standardized nomenclature, but the devices we've sold to customers can come back for repair, maintenance and calibration for decades: so we can't ever get rid of the old system.
The new string variant looks like this:
XXX-0000
XXX-00000
XXX-000000
I've modified the original regex to accommodate the change: [\\w{3}-]*\\d{4,5}[\\.?\\w*]{0,4}
I've also tried \p{L}{3}?-?\d{4,6}\.?\w{0,2}\.?\w{0,2}
, but that exhibits the same problem (see immediately below).
Both work, but in my testing I've noticed that they will allow a seemingly infinite number of extra characters to be tacked onto the end of the valid possibilities. (I'm pretty sure the old regex allowed the same type of bad input.)
So, to trap for the new string, I'd need to look for three letters followed by a dash, followed by four to six digits (something like this: [\w{3}-]?\d{4,6}?
or [/p{L}{3}-]?\d{4,6}?
)...and also accommodate the previous drawing names, four to five digits possibly followed by a single letter, digit or a single decimal point, possibly followed by a single letter or digit, possibly followed by a single digit or letter (confusing, huh?) – something like this: \d{4,5}[\.\w*]{0,4}
I think the problem with this part lies in the asterisk following the w
, but I'm not sure how to fix it or properly concatenate the two different parts of the regex together.
What I'm looking for is hopefully a single regex that'll allow me to screen for valid input with all of the string variants above, but block on invalid input. I know I can simply add another validation rule, and that might be what I have to do, but I wanted to see if it's possible to do it in a single regex.
Edit:
Here is the final solution as suggested by Lucas that I'm using in my code, modified somewhat to not use the \w
as pointed out in his answer below:
(?:\\d{4,5}[0-9a-zA-Z]{0,2}(?:\\.[0-9a-zA-Z]{1,2})?|[a-zA-Z]{3}-\\d{6})