I'm running into a problem with this regex for TCP Flag validation.
Here is my current version (I've been though many, all are wrong in some way):
^([AFPRSU](?![0-9]))(?!\1)|((?<![A-z])[1-9] [0-9]*)$
So, the value can either be any non-repeating combination of TCP Flags (A,F,P,R,S,U) or the integer equivalent.
Valid:
A,
AFP,
FPURA,
18,
1,
40
Invalid:
empty/null/whitespace,
AA,
aFP,
a100,
100a,
XFP
The problem with my current regex is the lookaheads/behinds only check one character /- so AFPx100
will be a valid value since "F" after "A" is valid. I had similar issues with different iterations, but ultimately it boils down to ignorance. I've been using trial and error on regexr.com but not really getting anywhere, been about 8 hours of effort so far.
I'm unfortunately bound to Regex or I would solve this a different way. At this point I'm desperate for any pointers/advice. Thanks.
CodePudding user response:
Using the anchors to match the whole string, you could match on or more chars out of [AFPRSU]
or 1 or more digits starting with a digit 1-9 so that also empty strings do not match:
^(?:(?![AFPRSU]*([AFPRSU])[AFPRSU]*\1)[AFPRSU] |[1-9]\d*)$
Explanation
^
Start of string(?:
Non capture group for the 2 alternatives(?![AFPRSU]*([AFPRSU])[AFPRSU]*\1)
Negative lookahead, assert not 2 of the same listed characters in the string[AFPRSU]
Match 1 times any of the listed characters|
Or[1-9]\d*
Match a digit 1-9 followed by optional digits
)
Close the non capture group$
End of string
See a regex demo.
const regex = /^(?:(?![AFPRSU]*([AFPRSU])[AFPRSU]*\1)[AFPRSU] |[1-9]\d*)$/;
[
"A",
"AFP",
"FPURA",
"18",
"1",
"40",
"",
" ",
"AA",
"aFP",
"a100",
"100a",
"XFP"
].forEach(s =>
console.log(`"${s}" --> ${regex.test(s)}`)
);