代码之家  ›  专栏  ›  技术社区  ›  Ian Kemp

使用流水线将字符串拆分为多维数组

  •  4
  • Ian Kemp  · 技术社区  · 6 年前

    请考虑以下字符串:

    $foo = @"
    cfa7b63c88ed1eb7443daeb12128084f17e1ac80
    85e59563f059ecf45c104bef1eac9d70c22150ed
    e207411bdb392a2d99719c221c8dd59e0dbebe26
    df61cb22643321198656bfa7061c4e415eefdfef
    3611ed35610793e814c8aa25715aa582ec08a8b6
    089dfe7ceb9a0845342a9637527de65245ba297f qwerty
    17570cc9387755367db0fc1c5c5f4757db7fd9b3 asdfgh
    82a1be2b77e949cb45581c4d25bf962f77041846 uiop
    0b726925f60c17795d4655f8ee37d51a3de70b87 lkjjh
    7ed66867332bf06486117189701278cdabd31da6 zxcv
    "@
    

    我想将它拆分为一个数组数组,这样输出如下所示:

    [0] => [ "089dfe7ceb9a0845342a9637527de65245ba297f", "qwerty" ]
    ...
    [4] => [ "7ed66867332bf06486117189701278cdabd31da6", "zxcv" ]
    

    换句话说,一个由5个元素组成的数组,每个元素都是2个元素的数组。请注意,必须排除缺少第二部分的行(即哈希之后无内容)。

    到目前为止我得到了这个:

    $bar = $foo -split "`r?`n" |?{ $_.length -gt 40 } |%{ $_.split(" ") }
    

    但结果是一个由10个元素组成的一维数组。

    再玩一点收益率:

    $bar = $foo -split "`r?`n" |?{ $_.length -gt 40 } |select { $_.split(" ") }
    

    它给了我一个5的数组,但是数组中的项是 PSCustomObject S与A NoteProperty 打电话 $_.split(" ") 它本身是一个由2个字符串组成的数组。如此接近,但迄今为止-如果我能把 小精灵 我会做生意的!

    是否有可能实现我的愿望,同时考虑到这些限制:

    • 一切都必须通过管道来完成
    • 没有显式命名哈希表元素,等等-我想要

    如果这是不可能的,或者我对powershell及其管道的工作原理有一些根本性的误解(我非常怀疑是这样),请教育我!

    2 回复  |  直到 6 年前
        1
  •  5
  •   iRon    6 年前

    如果要将数组放在管道中并防止powershell将其作为单独的管道项放置,则需要通过在数组对象前面放置逗号将其强制为.NET数组列表:

    PS C:\> $bar = $foo -split "`r?`n" | %{ ,$_.split(" ", 2) }
    PS C:\> $bar[7]
    82a1be2b77e949cb45581c4d25bf962f77041846
    uiop
    PS C:\> $bar[7][1]
    uiop
    
        2
  •  1
  •   boxdog    6 年前

    这有点笨重,但我认为它符合您的要求:

    $foo = @"
    cfa7b63c88ed1eb7443daeb12128084f17e1ac80
    85e59563f059ecf45c104bef1eac9d70c22150ed
    e207411bdb392a2d99719c221c8dd59e0dbebe26
    df61cb22643321198656bfa7061c4e415eefdfef
    3611ed35610793e814c8aa25715aa582ec08a8b6
    089dfe7ceb9a0845342a9637527de65245ba297f qwerty
    17570cc9387755367db0fc1c5c5f4757db7fd9b3 asdfgh
    82a1be2b77e949cb45581c4d25bf962f77041846 uiop
    0b726925f60c17795d4655f8ee37d51a3de70b87 lkjjh
    7ed66867332bf06486117189701278cdabd31da6 zxcv
    "@
    
    $foo | ForEach-Object {$array = New-Object System.Collections.ArrayList}{
        $match = [Regex]::Match($foo, "(?<code1>\w+) (?<code2>\w+)")
    
        while($match.Success)
        {
            $array.Add(@($match.Groups["code1"].Value, $match.Groups["code2"].Value)) | Out-Null
    
            $match = $match.NextMatch()
        }
    }{$array}
    

    输出是一个数组数组(每个数组都有来自 $foo ,然后可以将管道标记到最后一个括号上并继续处理。