the following is my regex
regex: /^[a-zA-Z] -.*(?=.*\d)(?=.*[a-zA-Z]).*-[0-9] -[a-zA-Z] -[0-9] $/
the overall rules is: alphabet-alphanumeric-number-alphabet-number
im having problem at .*(?=.*\d)(?=.*[a-zA-Z]).*
the expected output for it to get a successful result for the alphanumeric part is
- abc123
- 123abc
- 1abc23
- ab23ca
and fail if
- abcde
- 12345
but the result i get is all successful include the expected fail result
- abc-abc-123-abc-123
- abc-123-123-abc-123
i see that using lookahead will also get the input after the dash(-) of the alphanumeric that caused it to be successful although it is not the expected result
CodePudding user response:
You could try
^[a-zA-Z] -(?![a-zA-Z] -|\d -)[a-zA-Z0-9] -\d -[a-zA-Z] -\d $
It uses this negative lookahead to check the second subsequence is not only made by alphabets or numerics
(?![a-zA-Z] -|\d -)
Alternatively, you can use this positive lookahead to check the second subsequence is made by a digit preceded any alphabets or the other way around
(?=[a-zA-Z] \d|\d [a-zA-Z])
It is important to use a lookahead to check it right at the start of the subsequence, and do not use .*
in this situation since it might consume a -
and checks the wrong sequence behind it.
You may check the test result here
CodePudding user response:
why not:
/([A-Za-z] [0-9] |[0-9] [A-Za-z] )/
-- or --
/[A-Za-z]/.test(val) && /[0-9]/.test(val)
var cases = [
"abc123",
"123abc",
"1abc23",
"ab23ca",
// fail
"abcde",
"12345",
"abc-abc-123-abc-123", // not clear if these should fail?
"abc-123-123-abc-123"
];
cases.forEach(val => {
var ok = /([A-Za-z] [0-9] |[0-9] [A-Za-z] )/.test(val)
//var ok = /[A-Za-z]/.test(val) && /[0-9]/.test(val);
console.log(val, ok);
});
CodePudding user response:
For the alphanumeric part, you can assert not only digits till the next hyphen.
Using a case insensitive match:
^[a-z] -(?!\d -)[a-z]*\d[a-z\d]*-\d -[a-z] -\d $
^
Start of string[a-z] -
Match 1 chars a-z and-
(?!\d -)
Negative lookahead, assert not only digits followed by-
[a-z]*\d[a-z\d]*-
Match optional chars a-z, match a digit and optional chars a-z or a digit\d -[a-z] -\d
Match digits-
chars a-z-
digits$
End of string
const regex = /^[a-z] -(?!\d -)[a-z]*\d[a-z\d]*-\d -[a-z] -\d $/i;
[
"abc-abc-123-abc-123",
"abc-123-123-abc-123",
"abc-abcde-123-abc-123",
"abc-12345-123-abc-123",
"abc-ab23ca-123-abc-123",
"abc-1abc23-123-abc-123"
].forEach(s =>
console.log(`${s} --> ${regex.test(s)}`)
);