无法从函数返回的变量索引到空数组,或访问返回的正则表达式数据时出现问题
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 无法索引到空数组