我需要在批处理脚本中验证字符串是否为有效的 IPv4 或 IPv6 地址,但显然批处理没有解析 IP 地址的简单方法。
如何在不使用外部工具的情况下在批处理中执行此操作?“外部工具”是指正常 Windows 安装中尚不存在的东西。
“有效的 IPv4 或 IPv6 地址”是指采用 IP 地址格式的字符串,类似字符串的误报999.999.999.999是可以的(即使一些基本过滤是受欢迎的)。根据经验,解决方案至少应该能够区分错误消息和地址。
我知道一个类似的问题已经存在,但是这个问题没有考虑 IPv6,而且它对“有效 IPv4 地址”的定义更加严格(类似999.999.999.999是不可接受的)。
回答
检查有效的 IPv4:
@if (@X)==(@Y) @end /* JScript comment @echo off cscript //E:JScript //nologo "%~f0" %* exit /b %errorlevel%@if (@X)==(@Y) @end JScript comment */WScript.Quit(ValidateIPaddress(WScript.Arguments.Item(0)));function ValidateIPaddress(ipaddress) { return !(/^(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?).(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/.test(ipaddress))}
对于有效的 IPv6 地址:
@if (@X)==(@Y) @end /* JScript comment @echo off cscript //E:JScript //nologo "%~f0" %* exit /b %errorlevel%@if (@X)==(@Y) @end JScript comment */WScript.Quit(ValidateIPaddress(WScript.Arguments.Item(0)));function ValidateIPaddress(ipaddress) { return !(/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/gm.test(ipaddress))}
两者都依赖于退出代码,因此它们的使用方法如下:
call validIPV4.bat 12.12.12.12 s criteria for IPv4. For v6 a simple group is probably required.
回答
经过一些试验(和谷歌搜索),我设法编写了一个函数,在 Powershell 的帮助下检查地址的有效性。
该函数需要一个变量名和一个字符串(用引号括起来)。如果字符串是有效的 IP,则变量的值设置为True,否则设置为False。
set "_ip=127.0.0.1"call :checkip _result "%_ip%"echo %_result%set "_ip=::1/128"call :checkip _result "%_ip%"echo %_result%set "_ip=Not an ip address"call :checkip _result "%_ip%"echo %_result%goto :eof:checkipsetlocalset _var=%1set _ip=%~2set _prefixlenght=%_ip:*/=%call set _ip=%%_ip:/%_prefixlenght%=%%for /F "usebackq tokens=*" %%g in (`powershell -c "$ipaddrobj = [ipaddress]::Any ; if (!([ipaddress]::TryParse('%_ip%', [ref]$ipaddrobj))){if (!([ipaddress]::TryParse('%_ip%'.split(':')[0], [ref]$ipaddrobj))){return $false}} ; return $true"`) do (set _ipvalid=%%g)endlocal t meet your own criteria of `999.999.999.999` being an acceptable input.
回答
这是使用 VbscriptRegEx来检查 IPv4 或 IPv6的尝试
正则表达式演示在这里
脚本
Option ExplicitDim Title,IP,Array_IPTitle = "Test the validity of an IP address IPv4 Or IPv6"ForceCScriptExecution(Title)Array_IP = Array(_ "1200:0000:AB00:1234:0000:2552:7777:1313",_ "192.168.1.1",_ "255.255.0.0",_ "172.16.18.21",_ "172.16.18.500",_ "1600:0000:AB30:1234:0000:2552:7777:1313",_ "172.16.300.21",_ "172.16.18.23",_ "172.256.18.21",_ "255.255.255.0",_ "255.255.255.255"_)For Each IP in Array_IP If Is_Valid(IP) = True Then Wscript.echo IP & " is a Valid IP Address" Else Wscript.echo IP & " is Not a Valid IP Address" End ifNextWscript.sleep 20000'------------------------------------------------------------------------------------Function Is_Valid(ip) Dim RegularExpressionObject Set RegularExpressiOnObject= New RegExp With RegularExpressionObject .Pattern = "(^((25[0-5]|2[0-4]d|1?d?d).){3}(25[0-5]|2[0-4]d|1?d?d)$)|(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" .IgnoreCase = False If .Test(ip)= True then Is_Valid = True end if End WithEnd Function'------------------------------------------------------------------------------------Sub ForceCScriptExecution(Title) Dim Arg, Str, cmd cmd = "CMD /C Title " & Title &" & color 0A & Mode 80,30 & " If Not LCase( Right( WScript.FullName, 12 ) ) = "cscript.exe" Then For Each Arg In WScript.Arguments If InStr( Arg, " " ) Then Arg = """" & Arg & """" Str = Str & " " & Arg Next CreateObject( "WScript.Shell" ).Run _ cmd & "cscript //nologo """ & _ WScript.ScriptFullName & _ """ " & Str WScript.Quit End IfEnd Sub'-------------------------------------------------------------------------------------
批处理文件:
@echo offTitle Test the validity of an IP address IPv4 Or IPv6set "_IP=1200:0000:AB00:1234:0000:2552:7777:1313"Call :CheckIp "%_IP%" Validityif [%Validity%] equ [0] ( color 0A echo "%_IP%" is a valid ip) else ( Color 0C echo "%_IP%" is not a valid ip)Pauseset "_IP=192.168.500.300"ClsCall :CheckIp "%_IP%" Validityif [%Validity%] equ [0] ( color 0A echo "%_IP%" is a valid ip) else ( Color 0C echo "%_IP%" is not a valid ip)PauseExit::--------------------------------------------------------------------------------------------------:CheckIP Set "VbsFile=%Temp%%~n0.vbs"( echo WScript.Echo(Is_Valid("%~1"^)^) echo Function Is_Valid(ip^) echo Dim RegularExpressionObject echo Set RegularExpressiOnObject= New RegExp echo With RegularExpressionObject echo .Pattern = "(^((25[0-5]|2[0-4]d|1?d?d).){3}(25[0-5]|2[0-4]d|1?d?d)$)|(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]).){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))" echo .IgnoreCase = False echo If .Test(ip^)= True then echo Is_Valid = 0 echo Else echo Is_Valid = 1 echo End if echo End With echo End Function)>"%VbsFile%"@for /f "delims=" %%a in ('cscript //nologo "%VbsFile%"') do set "%2=%%a"Exit /B::--------------------------------------------------------------------------------------------------
回答
如何在不使用外部工具的情况下在批处理中执行此操作?“外部工具”是指正常 Windows 安装中尚不存在的东西。
您可以使用与所有 Windows 计算机捆绑在一起的 powershell,即:
ip_validate.bat
@echo offpowershell -Command "[ipaddress]::TryParse('192.168.1.1',[ref][ipaddress]::Loopback)"powershell -Command "[ipaddress]::TryParse('192.168.1.256',[ref][ipaddress]::Loopback)"powershell -Command "[ipaddress]::TryParse('2001:0db8:85a3:0000:0000:8a2e:0370:7334',[ref][ipaddress]::Loopback)"powershell -Command "[ipaddress]::TryParse('20ddd01:0db8:85a3:0000:0000:8a2e:0370:7334',[ref][ipaddress]::Loopback)"
输出:
TrueFalseTrueFalse