简体   繁体   English

正则表达式IF条件

[英]Regex IF condition

I'm looking for a way to filter new IP-Addresses in my host file. 我正在寻找一种过滤主机文件中新IP地址的方法。 I created a script which updates my host file every time when I call it with data from the matrix enterprise manager. 我创建了一个脚本,该脚本每次使用矩阵企业管理器中的数据调用主机文件时都会对其进行更新。 It works fine. 工作正常。 But I have to find a solution that only 10.XX.XX.XX or 172.XX.XX.XX addresses are allowed to update. 但是我必须找到一种解决方案,仅允许更新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

Your code is unnecessarily convoluted and doesn't make proper use of the features PowerShell provides. 您的代码被不必要地弄乱了,并且没有正确使用PowerShell提供的功能。

  • Don't assign $args[...] to parameters. 不要将$args[...]分配给参数。 That's not how parameter handling in PowerShell works. 这不是PowerShell中参数处理的工作方式。 Make the parameters mandatory instead. 将参数改为强制性。
  • % {if ($_ -notmatch $Match) {$_}} is better phrased as Where-Object {$_ -notmatch $Match} . % {if ($_ -notmatch $Match) {$_}}最好用Where-Object {$_ -notmatch $Match}
  • If $Match is an FQDN the dots might cause false positives (because they match any character, not just literal dots). 如果$Match是FQDN,则点可能会导致误报(因为它们匹配任何字符,而不仅仅是文字点)。 Either escape $Match ( [regex]::Escape($Match) ) or use the -notlike operator instead. 转义$Match[regex]::Escape($Match) )或改用-notlike运算符。
  • PowerShell has an escape sequence for tabs ( `t ). PowerShell具有制表符( `t )的转义序列。 No need to define a variable with a value of [char]9 . 无需定义一个值为[char]9的变量。
  • Putting variables in a double-quoted string ( "$var1$var2" ) is often more readable than string concatenation ( $var1 + $var2 ). 将变量放在双引号字符串( "$var1$var2" )中通常比字符串连接( $var1 + $var2 )更易读。

Change your code to something like this: 将您的代码更改为如下所示:

[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
}

If you want to avoid writing the output file multiple times, you could collect the data read in a variable, and then write that variable and the new record in one go: 如果要避免多次写入输出文件,可以收集在变量中读取的数据,然后一次性写入该变量和新记录:

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

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

$hosts | Set-Content $SourceFile

You could further optimize your script by doing the check via parameter validation , so you don't need an if condition in the function body in the first place, eg like this: 您可以通过通过参数验证进行检查来进一步优化脚本,因此首先不需要在函数体中使用if条件,例如:

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

or like this: 或像这样:

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

Some of the comments above use regex to validate the entire IPv4 address. 上面的某些注释使用正则表达式来验证整个IPv4地址。 If you are confident that the IP address you are checking is valid, then you can use "^(10|172)\\." 如果您确定要检查的IP地址有效,则可以使用"^(10|172)\\." to verify just the first octet of the address as per your question: 根据您的问题仅验证地址的第一个八位字节:

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

If you do want to validate the whole address, there is an alternative way to do this by converting $newIP to a [System.Net.IPAddress] type. 如果确实要验证整个地址,则可以通过将$ newIP转换 [System.Net.IPAddress]类型来实现。 If this fails the result will be nothing (null), which is implicitly false, so the following gives you a true/false check that a string is a valid IP address: 如果失败,则结果将为空(null),即隐式为false,因此以下内容为您提供了对字符串是否为有效IP地址的正确/错误检查:

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

You could use this to validate the input to the function written by Ansgar: 您可以使用它来验证Ansgar编写的函数的输入:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM