如果在PowerShell中不包含任何数组值,则写出字符串

时间:2017-05-18 13:30:24

标签: arrays string powershell if-statement foreach

我这里有一个简单的程序,它会在行数中写出一行,如果它不包含另一个数组中的任何名称。

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
   if ($line -notmatch $names)
   {
       write $line
   }
}

当我运行它时,它只是写出行数组中的每一行,即使'Adam'包含在名称数组中。它应该写出'我的名字是吉姆'和'我的名字是山姆'。

很抱歉,如果这个问题非常基本,但我找不到任何答案。

3 个答案:

答案 0 :(得分:2)

如果您正在使用与-notmatch进行正则表达式比较,为什么不将您的名称列表转换为更好的正则表达式?这样的事情怎么样:

$names = "Adam", "Bill", "Colin", "Dave"
$lines = "My name is Jim", "My name is Sam", "My name is Adam"

$regex = $names -join '|'

$lines | ? {$_ -notmatch $regex} | % {Write-Host $_}

答案 1 :(得分:1)

可能有一个比这更好的解决方案,但解决它的一种方法是使用第二个循环遍历每个名​​称并在行中检查它们:

[array]$names = "Adam", "Bill", "Colin", "Dave"
[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

foreach ($line in $lines)
{
    $names | ForEach-Object -Begin {$found = $false} {
        If ($line -match $_){ $found = $true; break } 
    } 

    if (-not $found)
    {
        write $line
    }
}

<强>解释

  • 通过管道将$ name发送到ForEach-Object。首先在其-Begin块中初始化$ found变量。
  • ForEach-Object检查与每个名称匹配的行(该名称现在是由$_表示的管道中的项目)。如果找到它,则将$ found设置为true并使用break结束循环。
  • 如果$ found不成立,则会写入该行。

答案 2 :(得分:0)

谢谢你的回答。我重新设计了我的代码,使其更简单:

[array]$names = "Adam", "Bill", "Colin", "Dave"

[array]$lines = "My name is Jim", "My name is Sam", "My name is Adam"

    foreach ($line in $lines)
    {
        $regex = $names -join '|'

        if ($line -notmatch $regex)
        {
            write $line
        }
    }