Batch file 用于格式为xxxx.xxxx.xxxx的MAC的批量正则表达式
我一直在尝试解析格式为“xxxx[Delimiter]xxxx[Delimiter]xxxx”的mac,其中“x”在[0-9,a-F,a-F]中,“Delimiter]”在[:,,-]中。我尝试了下面的代码,并引用了带有标题和标题的示例 我也试过这个Batch file 用于格式为xxxx.xxxx.xxxx的MAC的批量正则表达式,batch-file,cmd,Batch File,Cmd,我一直在尝试解析格式为“xxxx[Delimiter]xxxx[Delimiter]xxxx”的mac,其中“x”在[0-9,a-F,a-F]中,“Delimiter]”在[:,,-]中。我尝试了下面的代码,并引用了带有标题和标题的示例 我也试过这个 echo %MACAddr%|findstr /r "^([0-9A-Fa-f]{4})([:.-])([0-9A-Fa-f]{4})([:.-])([0-9A-Fa-f]{4})$" 但是只有当errorlevel 1(echo Mac%MAC
echo %MACAddr%|findstr /r "^([0-9A-Fa-f]{4})([:.-])([0-9A-Fa-f]{4})([:.-])([0-9A-Fa-f]{4})$"
但是只有当errorlevel 1(echo Mac%MACAddr%与xxxx.xxxx.xxxx格式不同)时,它才会运行
。
。请告诉我我做错了什么。findstr
的REGEX子集非常有限(请参见了解/?
)
你的要求可以表述为:
findstr /ri "^[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]$"
其中
表示“任何字符”。如果你想把它分解成
、
和-
作为分隔符,使用[;.-]
而不是
。如果分隔符可能存在或不存在,请使用[;.-]*
(其中*
表示“零或多”-抱歉,没有?
“无”或“一”与findstr
)你知道当你遇到这样的问题时,你必须一直坚持下去直到找到解决方案吗?
因此,第一部分只是生成一系列用于测试的“可能”条目。带有macaddr
分配给测试字符串的例程:testmacaddr
实际执行工作,标签:report
后的部分报告结果-如果定义了invalid
,则提供的macaddr
因%invalid%
中的原因无效
%%d循环的检查初始或终端分隔符,并在:tokenise
例程中为内部循环建立控制字符串
:tokenise
例程使用当前分隔符检查前四个令牌的提供地址,将八位字节分配给%%p..%s。因为我们想要的正好是3,所以%%s
必须为空,%%r
不为空才能使用:validate进行进一步验证
:validate
检查每个八位字节是否与/x
完全匹配/i
对/r
正则表达式1,2,3或4个十六进制数字不区分大小写。如果八位字节未通过所有这些测试,invalid
被设置为失败的八位字节数。如果所有八位字节都通过,则valid
设置为Y
因此,如果没有失败的条件,并且:validate
例程被传递了一次,那么该值是有效的。如中所述,findstr
没有完全的正则表达式支持
因此,不支持分组((
/)
)、备选方案(
)、重复({
/}
)和选项(?
)
还有一个需要考虑的额外限制:字符类([
/]
)的数量限制为15,因此指定16个或更多会导致错误。
还不够,字符类有缺陷,它们可能匹配意外字符;例如,范围[0-9]
匹配十进制数字0
到9
,但也匹配字符2
和3
;范围[A-Z]
(不带/I
选项)也错误地匹配小写字母,如Z
,还匹配一些其他字符,如Á
或á
,具体取决于当前代码页
有关findstr
的所有缺陷和限制,请参阅《大词典》
要解决所有这些问题,您可以指定多个搜索字符串,如findstr/R“search\u string1 search\u string2”
(空格分隔列表)或findstr/R/C:“search string1”/C:“search string2”
(这甚至允许空格成为搜索字符串的一部分)
我会这样做你的任务:
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]”^
/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]。”^
/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]”^
/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]”^
/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]:”^
/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]。”^
)
您也可以在不使用/C
的情况下使用语法,但阅读起来很糟糕:
[0-9A-F][0-9A-F][0-9A-9A-F][0-9A-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-9A-F][[0-9A-9A-F][[0-9A-9A-F][[0-9A-9A-F][0-9A-9A-9A-F][0-F[0-9A-9A-9A-F[0-9A-F[0-9A-F[0-9A-9A-F-F[0-F[0-9A-9A-F[0-F-F-9-F][[0-9A-9A-9A-F][[0-9-F-F[0-F[0-[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-9A-F[0-9A-F[0-9A-F][0-9A-9A-F[0-9A-F[0-9A-F[0-9A-F[0-9A-F[0-9A-9A-F[0-9A-9A-F[0-9A-F[0-9A-F][0-9A-9A-F][0-9A-9A-F[0-F][0-9A-F[0-9A-F][0-9A-F[0-9A-F][0-9A-F][0-F[0-9A-F[0-9-F[0-9A-F[0-F[0-9-9-9-F[0-9A-F[0-9-F[0-F[0-9-9-9-9-9-9-9-[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]。”
您可以将搜索字符串放入文本文件(例如MACAddrRegEx.txt
)并使用以下语法:
echo%MACAddr%| findstr/I/X/R/G:“MACAddrRegEx.txt”
而MACAddrRegEx.txt
的内容是:
[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
findstr /ri "^[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]$"
@ECHO Off
SETLOCAL ENABLEDELAYEDEXPANSION
:: This simply tests various addresses
FOR %%D IN (":" "." "-" "#") DO FOR %%T IN (
.012a.23fa.5ffc
012a.23fa.5ffc.
012a.23fa.5ffc
012a.23fa
012a.23fa.5ffc.0123
01ka.23fa.5ffc
012a.23ga.5ffc
012a.23fa.5pfc
012a1.23fa.5ffc
012a.263fa.5ffc
012a.23fa.58ffc
1.2.3
03ed.2.f
) DO (
set "MACAddr=%%T"
SET "macaddr=!macaddr:.=%%~D!"
CALL :testmacaddr
)
SET "macaddr="
CALL :testmacaddr
GOTO :eof
:testmacaddr
SET "invalid="
SET "valid="
If NOT DEFINED MACAddr SET "invalid=MACADDR not set"&GOTO report
FOR %%d IN (":" "." "-") DO (
IF "%macaddr:~0,1%"=="%%~d" SET "invalid=Initial"
IF "%macaddr:~-1%"=="%%~d" SET "invalid=Terminal"
SET "control="tokens=1-4delims=%%~d""
CALL :tokenise
)
:report
IF NOT DEFINED valid IF NOT DEFINED invalid SET "invalid=Incorrect octet count"
:: pad 'macaddr' with a goodly number of spaces,
:: show the first 20 character of the result and the 'invalid' value
SET "macaddr=%macaddr% "
ECHO %macaddr:~0,20% : %invalid%
GOTO :EOF
:tokenise
FOR /f %control% %%p IN ("%macaddr%") DO (
IF "%%s"=="" IF "%%r" neq "" (
SET /a octets=1
CALL :validate %%p %%q %%r
)
)
GOTO :eof
:validate
ECHO %1|FINDSTR /r /x /i "[0-9a-f]">NUL
IF NOT ERRORLEVEL 1 GOTO valok
ECHO %1|FINDSTR /r /x /i "[0-9a-f][0-9a-f]">NUL
IF NOT ERRORLEVEL 1 GOTO valok
ECHO %1|FINDSTR /r /x /i "[0-9a-f][0-9a-f][0-9a-f]">NUL
IF NOT ERRORLEVEL 1 GOTO valok
ECHO %1|FINDSTR /r /x /i "[0-9a-f][0-9a-f][0-9a-f][0-9a-f]">NUL
IF ERRORLEVEL 1 SET "invalid=Octet %octets%"&GOTO :eof
:valok
shift
SET /a octets+=1
IF %octets% lss 4 GOTO validate
SET "valid=Y"
GOTO :eof