正则表达式IF条件

时间:2017-06-08 08:32:09

标签: regex powershell

我正在寻找一种在主机文件中过滤新IP地址的方法。 我创建了一个脚本,每当我用矩阵企业管理器中的数据调用它时,它都会更新我的主机文件。它工作正常。但我必须找到一个只允许更新10.XX.XX.XX或172.XX.XX.XX地址的解决方案。

Param(
  $newHost = $args[0],
  $newIP = $args[1]
)

$SourceFile = "hosts"
$Match = "$newHost"

(Get-Content $SourceFile) | % {if ($_ -notmatch $Match) {$_}} | Set-Content $SourceFile

Start-Sleep -Seconds 1

$tab = [char]9
$enter = $newIP + $tab + $newHost

if ($newIP XXXX)  #--> here should be a regex if condition... no clue how it works..

$enter | Add-Content -Path hosts

2 个答案:

答案 0 :(得分:4)

您的代码不必要地复杂化,并且没有正确使用PowerShell提供的功能。

  • 不要将$args[...]分配给参数。这不是PowerShell中parameter handling的工作方式。强制使用参数。
  • % {if ($_ -notmatch $Match) {$_}}更好地表达为Where-Object {$_ -notmatch $Match}
  • 如果$Match是FQDN,则点可能会导致误报(因为它们匹配任何字符,而不仅仅是文字点)。请转义$Match[regex]::Escape($Match))或使用-notlike运算符。
  • PowerShell有一个标签转义序列(`t)。无需定义值为[char]9的变量。
  • 将变量放在双引号字符串("$var1$var2")中通常比字符串连接($var1 + $var2)更具可读性。

将您的代码更改为以下内容:

[CmdletBinding()]
Param(
  [Parameter(Mandatory=$true)]
  [string]$Hostname,
  [Parameter(Mandatory=$true)]
  [string]$IPAddress
)

$SourceFile = 'hosts'

(Get-Content $SourceFile) |
  Where-Object { $_ -notlike "*$Hostname*" } |
  Set-Content $SourceFile

Start-Sleep -Seconds 1

if ($IPAddress -match '^(10|172)\.') {
  "$IPAddress`t$Hostname" | Add-Content $SourceFile
}

如果要避免多次写入输出文件,可以收集变量中读取的数据,然后一次性写入该变量和新记录:

$hosts = @(Get-Content $SourceFile) | Where-Object { $_ -notlike "*$Hostname*" })

if ($IPAddress -match '^(10|172)\.') {
  $hosts += "$IPAddress`t$Hostname"
}

$hosts | Set-Content $SourceFile

您可以通过parameter validation进行检查来进一步优化您的脚本,因此您首先不需要函数体中的if条件,例如像这样:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Hostname,
  [Parameter(Mandatory=$true)]
  [ValidatePattern('^(10|172)\.')]
  [string]$IPAddress
)

或者像这样:

Param(
  [Parameter(Mandatory=$true)]
  [string]$Hostname,
  [Parameter(Mandatory=$true)]
  [ValidateScript({$_ -match '^(10|172)\.' -and [bool][ipaddress]$_})]
  [string]$IPAddress
)

答案 1 :(得分:3)

上面的一些评论使用正则表达式来验证整个IPv4地址。如果您确信要检查的IP地址有效,那么您可以使用"^(10|172)\."根据您的问题验证地址的第一个八位字节:

if($newIP -match "^(10|172)\.") { ... }

如果您确实要验证整个地址,可以通过将 $ newIP 转换为[System.Net.IPAddress]类型来实现此目的。如果失败,结果将为空(null),这隐式为false,因此以下内容为您提供了一个字符串是有效IP地址的真/假检查:

[bool]($newIP -as [System.Net.IPAddress])

您可以使用它来验证Ansgar编写的函数的输入:

[Parameter(Mandatory=$true)]
[ValidateScript({[bool]($_ -as [System.Net.IPAddress]})
[string]$IPAddress