无法从函数返回的变量索引到空数组,或访问返回的正则表达式数据时出现问题

Posted

技术标签:

【中文标题】无法从函数返回的变量索引到空数组,或访问返回的正则表达式数据时出现问题【英文标题】:Cannot index into null array from function returned variable, or issues accessing regex data returned 【发布时间】:2022-01-19 18:35:51 【问题描述】:

我不确定我是否从函数中错误地返回了值,但是当我尝试访问它的信息时,它会出现上述错误,

无法索引到空数组

我尝试了几种不同的方法,但我不确定我是否没有从函数中正确返回它,或者我只是访问了错误返回的信息。看着Cannot index into null array,对他来说,他的一些数组有空值。但是当我在退出该功能之前将我的信息打印到屏幕上时,它有信息。如何返回在函数中找到的值,以便我可以遍历主代码中的内容并使用对象中的字符串之一?这是parsing repeated pattern的延续。

#parse data out of cpp code and loop through to further process
#function
Function Get-CaseContents
  [cmdletbinding()]
  Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
  Process
  
     
     # construct regex
     $fullregex = [regex]"_stprintf[\s\S]*?_T\D*", # Start of error message, capture until digits
    "(?<sdkErr>\d+)",       # Error number, digits only
    "\D[\s\S]*?",           # match anything, non-greedy
    "(?<sdkDesc>\((.+?)\))", # Error description, anything within parentheses, non-greedy
    "([\s\S]*?outError\s*=(?<sdkOutErr>\s[a-zA-Z_]*))", # Capture OutErr string and parse out part after underscore later
    "[\s\S]*?",             # match anything, non-greedy
    "(?<sdkSeverity>outSeverity\s*=\s[a-zA-Z_]*)", # Capture severity string and parse out part after underscore later
    '' -join ''
    
    # run the regex
    $Values = $parsedCaseMethod | Select-String -Pattern $fullregex -AllMatches

    # Convert Name-Value pairs to object properties
    $result = foreach ($match in $Values.Matches)
      [PSCustomObject][ordered]@
        sdkErr      = $match.Groups['sdkErr']
        sdkDesc     = $match.Groups['sdkDesc']
        sdkOutErr   = $match.Groups['sdkOutErr']
        sdkSeverity = ($match.Groups['sdkSeverity'] -split '_')[-1] #take part after _
      
    

    #Write-Host "result:" $result -ForegroundColor Green
    $result
    return $Values
...

#main code
...
#call method to get case info (sdkErr, sdkDesc, sdkOutErr, sdkSeverity)
           $ValuesCase = Get-CaseContents -parsedCaseMethod $matchFound -parseLinesGroupIndicator "_stprintf" #need to get returned info back
           $result = foreach ($match in $ValuesCase.Matches)
              [PSCustomObject][ordered]@
                sdkErr      = $match.Groups['sdkErr']
                sdkDesc     = $match.Groups['sdkDesc']
                sdkOutErr   = $match.Groups['sdkOutErr']
                sdkSeverity = ($match.Groups['sdkSeverity'] -split '_')[-1] #take part after _
               #result
            #foreach ValuesCase

发送给函数解析的字符串示例为:

...
case kRESULT_STATUS_Undefined_Opcode:                       
            _stprintf( outDevStr, _T("8004 - (Comm. Err 04) - %s(Undefined Opcode)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_Comm_Timeout:                       
            _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;

        case kRESULT_STATUS_TXD_Failed:                     
            _stprintf( outDevStr, _T("8006 - (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.)"), errorStr);
            outError    = INVALID_PARAM;
            outSeverity = CCA_WARNING;
            break;
...

我尝试的另一件事是(但它也有索引到空数组的问题):

foreach($matchRegex in $ValuesCase.Matches)

      $sdkOutErr   = $matchRegex.Groups['sdkOutErr']
      Write-Host sdkOutErr -ForegroundColor DarkMagenta

最终,我需要获取 $sdkOutErr 以进一步处理。我还需要在返回的对象中使用其他变量,但这是我需要的第一个。我喜欢在函数中格式化输出的方式,但可能不知道如何返回信息并使用返回的内容。除了错误消息之外,我不确定要搜索什么来找出问题,这让我相信我返回的信息是错误的。我认为我不需要返回 $result,因为我认为这只是一个字符串,其中包含函数中 $values.Matches 中的值。如前所述,我需要访问返回的值。

我查了一下,发给函数的内容不是空白的。

我试过返回$results,写Host的时候是这样的,每个sdkOutErr都很难访问:

@sdkErr=1000; sdkDesc=(Out of Memory); sdkOutErr= NO_MEMORY; sdkSeverity=FATAL @sdkErr=1002; sdkDesc=(Failed to load DLL); sdkOutErr= OTHER_ERROR; sdkSeverity=FATAL @sdkErr=1003; sdkDesc=(Failed to load DLL); sdk
OutErr= OTHER_ERROR; sdkSeverity=FATAL @sdkErr=1004; sdkDesc=(Failed to open); sdkOutErr= OTHER_ERROR; sdkSeverity=FATAL @sdkErr=1005; sdkDesc=(Unable to access the specified profile); sdkOutErr= OTHER_ERROR; sdkSeverity=
FATAL @sdkErr=100 ...

如何从函数中返回它,使其不是空数组/索引,并且如果我在主代码中使用一个(或两个)foreach 循环来获取 sdkOutErr(开始),则可以访问数据。

我对(复杂的)powershell 相当陌生,我觉得我需要在我的函数中的数组中添加一个映射,但我不确定。

在我返回函数值或结果之前,它正在打印类似这样的内容。一旦我添加了 main $ValuesCase=Get-CaseContents...(从函数返回 $values)或 $parsedCase = Get-CaseContents...(从函数返回 $results),它就停止在屏幕上显示:

sdkErr sdkDesc                                                                                                                       sdkOutErr                                  sdkSeverity
------ -------                                                                                                                       ---------                                  -----------
1000   (Out of Memory)                                                                                                                NO_MEMORY                         FATAL      
1002   (Failed to load DLL)                                                                                                OTHER_ERROR                       FATAL      
1003   (Failed to load DLL)                                                                                             OTHER_ERROR                       FATAL      
1004   (Failed to open)                                                                                                      OTHER_ERROR                       FATAL  

【问题讨论】:

你为什么要return $Values?你已经输出了$results 因为我需要使用每一个 OutErr,并且无法通过 ='s 访问它 【参考方案1】:

我试过返回$results,写Host的时候是这样的,每个sdkOutErr都很难访问:

获取所有sdkOutErr 值并不像您想象的那么困难:

$results.sdkOutErr # this will output the `sdkOutErr` value from each object in the array

或者,在函数之外:

(Get-CaseContents -parsedCaseMethod $matchFound -parseLinesGroupIndicator "_stprintf").sdkOutErr

如果结果集很大,另一个可能会执行得更好的选项是使用 ForEach-Object 来获取 sdkOutErr 值:

$fullResults = Get-CaseContents -parsedCaseMethod $matchFound -parseLinesGroupIndicator "_stprintf"
$sdkOutErrValuesOnly = $fullResults |ForEach-Object -MemberName sdkOutErr

【讨论】:

对于第二件事(外部函数),您是使用返回的 $results 还是返回的 $Values?您是否意识到 sdkErr、sdkDesc、sdkOutErr 和 sdkSeverity 的 $results 列表超过 100 行?仅使用 .sdkOutErr 将如何工作? @Michele 假设您是return $results(忘记$values,您已经处理了这些)。不管它是 1、100 还是 100 万行 - PowerShell 将无法在结果数组对象上找到 sdkOutErr 属性,并将自动开始枚举各个数组项的属性值。 目前还不清楚我将如何迭代返回的 $results 列表中的每个项目。 如果不想使用属性枚举,使用循环:foreach($result in $results) Write-Host $result.sdkOutErr 谢谢!它现在似乎正在工作! :)

以上是关于无法从函数返回的变量索引到空数组,或访问返回的正则表达式数据时出现问题的主要内容,如果未能解决你的问题,请参考以下文章

便利的对象

Azure Runbook 错误,AzureRmStorageAccountKey 无法索引到空数组

C ++通过访问器函数返回私有二维数组

创建函数-----------(向函数传递数组从函数返回数组)

从函数返回时访问数组元素

从函数返回的访问数组 - javascript/jquery noob moment