在PowerShell中针对大型阵列的大量正则表达式删除非常慢

时间:2018-06-25 12:22:26

标签: arrays regex powershell powershell-v5.0

我试图找到对阵列运行许多正则表达式删除的最快/最有效的方法。

我的event数组包含成千上万个域格式的单个项目。例如:

  • test.domain.xyz

  • domain.xyz

  • something.com

  • anotherdomain.net

我的$hosts数组包含多行格式的〜1000个个人正则表达式。例如:

  • ^ ad。 (ad。*)

  • domain.xyz $(* domain.xyz)

我目前正在尝试通过以下方式排除任何正则表达式匹配项,但是对于大型数组和许多要匹配的正则表达式来说,它速度非常慢:

$local_regex

有更好的方法吗?

3 个答案:

答案 0 :(得分:2)

重新分配大型阵列将很昂贵。更改数组的大小需要分配一个新数组并将其内容复制到其中。例如,如果您拥有10000个主机名和1000个正则表达式,那么您将进行10,000万个复制操作。这将产生一定的效果。有一个cmdlet Measure-Command用于计时执行时间。

作为一种替代方法,请尝试使用索引数组并用$null值覆盖不需要的值。像这样

foreach($regex in $local_regex) {
    $regex = "(?im)$regex"
    for($i=0;$i -lt $hosts.length; ++$i) {
        if( $hosts[$i] -match $regex) {
            $hosts[$i] = $null
        }
    }
}

答案 1 :(得分:1)

您可以使用System.Collections.ArrayList对象而不是数组,这将使处理过程更快,并且您可以在不重建整个数组的情况下添加/删除项目

$var = New-Object System.Collections.ArrayList

$var.Add()
$var.AddRange()
$var.Remove()
$var.RemoveRange()

答案 2 :(得分:0)

如@Roberto所建议,我将$hosts数组切换为New-Object System.Collections.ArrayList

即时从ArrayList中删除的功能正是我所需要的,而while循环可确保删除重复的值。

Function Regex-Remove
{
    Param
    (
        [Parameter(Mandatory=$true)]
        $local_regex,
        [Parameter(Mandatory=$true)]
        $hosts
    )

    # Loop through each regex and select only non-matching items
    foreach($regex in $local_regex)
    {
        # Multi line, case insensitive
        $regex = "(?i)$regex"

        # Select hosts that do not match regex
        $hosts -match $regex | % {
            while($hosts.Contains($_))
            {
                $hosts.Remove($_)
            }
        }
    }

    return $hosts
}