As Stephan already mentioned in his answer, findstr
does not have full RegEx support.
So grouping ((
/)
), alternatives (|
), repetitions ({
/}
) and options (?
) are not supported.
There is an additional limitation that needs to be taken into account: the number of character classes ([
/]
) is limited to 15, so specifying 16 or more results in an error.
And not enough, character classes are buggy, they might match unexpected characters; for instance, the range [0-9]
matches the decimal figures 0
to 9
, but also characters ²
and ³
; the range [A-Z]
(without the /I
option) matches also lower-case letters erroneously, like z
, and also some other characters, like Á
or á
, depending on the current code page.
Refer to the great post by dbenham concerning all the bugs and limitations of findstr
.
To work around all that, you can specify multiple search strings, like findstr /R "search_string1 search_string2"
(white-space-separated list) or findstr /R /C:"search string1" /C:"search string2"
(this even allows white-spaces to be part of the search strings).
I would do your task like this:
echo %MACAddr%| (findstr /I /X /R ^
/C:"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" ^
/C:"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" ^
/C:"[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]" ^
/C:"[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]" ^
/C:"[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]" ^
/C:"[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]" ^
)
You can also use the syntax without /C
, but it is terrible to read:
echo %MACAddr%| findstr /I /X /R "[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F] [0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F] [0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F] [0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F] [0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F] [0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]"
You can put the search strings into a text file (say MACAddrRegEx.txt
) and use this syntax:
echo %MACAddr%| findstr /I /X /R /G:"MACAddrRegEx.txt"
And the content of MACAddrRegEx.txt
is:
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F][0-9A-F][0-9A-F]
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F]:[0-9A-F][0-9A-F][0-9A-F][0-9A-F]
[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]-[0-9A-F][0-9A-F][0-9A-F][0-9A-F]
[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]\.[0-9A-F][0-9A-F]
[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]:[0-9A-F][0-9A-F]
[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]-[0-9A-F][0-9A-F]
Remove the former three search strings if you do not want to accept strings with hexadecimal digits in groups of four; remove latter three ones if you do not want to accept strings in groups of two.
The aforementioned bug concerning upper- and lower-case-matching against letter ranges does not apply here since the /I
option is specified, which defines to do case-insensitive searches. However, the other range-related bugs are ignored here as otherwise, the search strings became extensively long (note that [0-9]
needed to be changed to [0123456789]
in order to match decimal digits only; same for letters) and so the length limit was going to be exceeded.