我試圖從檔案中決議出幾個重復的組(對于每個案例陳述,我需要 stprintf 中的數字(例如 8000)、后面的描述(例如 Comm Err 05 - 超時發送命令),以及嚴重性(警告或致命)。由于某種原因,結果是空的。我看了這個match 和 nomatch,我想我正在做他們應該做的事情。有沒有人看到我的問題,或者有任何其他建議?
#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
[cmdletbinding()]
Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
Process
{
Write-Host "This is what I'm dealing with people" -ForegroundColor Green
Write-Host $parsedCaseMethod
#parse the case data out:
#ex from code:
#case kRESULT_STATUS_PPA_Comm_Timeout: #_stprintf is parseLinesGroupIndicator
# _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
# outError = INVALID_PARAM;
# outSeverity = CCA_WARNING;
$regex = [regex]"\((.*)\)" #sdkErr
$severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
$parsedCaseMethod -match '$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)'
Write-Output "sdkErr:"
$Matches.sdkErr
Write-Output "sdkDesc:"
$Matches.sdkDesc
Write-Output "sdkSeverity:"
$Matches.sdkSeverity
}#End of Process
}#End of Function
#main code
...
#call method to get case info
Get-CaseContents -parsedCaseMethod $matchFound -parseLinesGroupIndicator "_stprintf" #need to get returned info back
$matchFound 內容的示例包括:
...
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;
...
如果找到的三個變數都在一個陣列中就可以了,所以從函式中回傳它們會更容易,但我還沒有達到那個程度。
對于方法 print 陳述句,它顯示了如上的字串內容,然后是以下空輸出:
bool
False
sdkErr:
sdkDesc:
sdkSeverity:
I would have expected it to ultimately return (I realize I don't have an array collecting this, but maybe the last group's info): sdkErr: 8004, sdkDesc: (Comm. Err 04) - %s(Undefined Opcode), sdkSeverity: Warning
sdkErr: 8005, sdkDesc: (Comm. Err 05) - %s(Timeout sending command), sdkSeverity: Warning
sdkErr: 8006, sdkDesc: (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.), sdkSeverity: Warning
This is PowerShell 5.1. If anyone has any suggestions, that would be much appreciated!
Update: I tried updating the input string so I know exactly what it's parsing, and it's only parsing one case statement. It's still returning nothing for sdkErr, and the other things it prints. it looks ok to me. I'm not sure what I'm missing. I was looking at backticks and decided I needed backticks etc in the substring I'm hard-coding because I was getting "input string was not in correct format" in my string I pulled out to test with. In the below change I'm re-defining the parameter to my smaller string for testing, and revised my regex for testing it, since what I had before didn't work.
#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
[cmdletbinding()]
Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
Process
{
#Write-Host "This is what I'm dealing with people" -ForegroundColor Green
#Write-Host $parsedCaseMethod
#parse the case data out:
#ex from code:
#case kRESULT_STATUS_Comm_Timeout: #_stprintf is parseLinesGroupIndicator
# _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
# outError = INVALID_PARAM;
# outSeverity = CCA_WARNING;
$parseCaseMethod = "case kRESULT_STATUS_Comm_Timeout:
_stprintf( outDevStr, _T(`"8005 - (Comm. Err 05) - %s(Timeout sending command)`"), errorStr);
outError = INVALID_PARAM;
outSeverity = CCA_WARNING;"
$regexNum = [regex]"$parseLinesGroupIndicator[\s\S.]*_T[.*](0-9)*"
$regex = [regex]"\((.*)\)" #sdkErr
$severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
##$parsedCaseMethod -match "$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
$parsedCaseMethod -match "$regexNum(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
Write-Output "sdkErr:"
$Matches.sdkErr
Write-Output "sdkDesc:"
$Matches.sdkDesc
Write-Output "sdkSeverity:"
$Matches.sdkSeverity
}#End of Process
}#End of Function
Update2: I was playing around with a regex editor regex101.com and it's matching with what I'm showing for $regexNum, but for some reason it's not returning what I expect when I print $Matches.sdkErr. I'm not sure if I't sbecause the editor shows the 8000 part as a Group and there's a different way to obtain it. I tried $Matches.sdkErr.Group(1) but get this error with that
Method invocation failed because [System.String] does not contain a method named 'Group'.
This is the code change (most of the change is in $regexNum):
#Function to get needed contents from case statements in $parsedCaseMethod provided
Function Get-CaseContents{
[cmdletbinding()]
Param ( [string]$parsedCaseMethod, [string]$parseLinesGroupIndicator)
Process
{
#Write-Host "This is what I'm dealing with people" -ForegroundColor Green
#Write-Host $parsedCaseMethod
#parse the case data out:
#ex from code:
#case kRESULT_STATUS_PPA_Comm_Timeout: #_stprintf is parseLinesGroupIndicator
# _stprintf( outDevStr, _T("8005 - (Comm. Err 05) - %s(Timeout sending command)"), errorStr);
# outError = INVALID_PARAM;
# outSeverity = CCA_WARNING;
$parsedCaseMethod = "case kRESULT_STATUS_Comm_Timeout:
_stprintf( outDevStr, _T(`"8005 - (Comm. Err 05) - %s(Timeout sending command)`"), errorStr);
outError = INVALID_PARAM;
outSeverity = CCA_WARNING;"
##$regexNum = [regex]"$parseLinesGroupIndicator[\s\Sa-zA-Z]*(0-9)*"
$regexNum = [regex]"$parseLinesGroupIndicator[\s\Sa-zA-Z]*_T[^[0-9]]*. ?([0-9][0-9]*)"
# \s\S\(`",a-zA-Z.]*_T[.*](0-9)*
$regex = [regex]"\((.*)\)" #sdkErr
$severity = [regex]"[\s\S.=;]*outSeverity[\s\S]*=[\s\Sa-zA-Z]*_(a-zA-Z)*" #severity warning or error etc
#$parsedCaseMethod -match "$parseLinesGroupIndicator[\s\S]*(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
#$parsedCaseMethod -match "$regexNum(?<sdkErr>\d*)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
$parsedCaseMethod -match "(?<sdkErr>$regexNum)[\s\S-]*(?<sdkDesc>$regex)(?<sdkSeverity>$severity)"
Write-Output "sdkErr:"
$Matches.sdkErr.Group(1) #error message...with $Matches.sdkErr it prints entire Match and not just the part in parenthesis that I want (8000)
Write-Output "sdkDesc:"
$Matches.sdkDesc
Write-Output "sdkSeverity:"
$Matches.sdkSeverity
}#End of Process
}#End of Function
I'm also looking at this string in text file
uj5u.com熱心網友回復:
您的正則運算式中有一些不正確的語法,請參閱下面有關建議替換的注釋。我也更喜歡使用Select-Stringover-match因為它可以回傳多個匹配項-AllMatches:
# construct regex, previously done with variables
$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
"[\s\S]*?", # match anything, non-greedy
"(?<sdkSeverity>outSeverity\s*=\s[a-zA-Z_]*)", # Capture severity string
'' -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']
sdkSeverity = $match.Groups['sdkSeverity']
}
}
$result
sdkErr sdkSeverity sdkDesc
------ ----------- -------
8004 outSeverity = CCA_WARNING (Comm. Err 04) - %s(Undefined Opcode)"), errorStr)
8005 outSeverity = CCA_WARNING (Comm. Err 05) - %s(Timeout sending command)"), errorStr)
8006 outSeverity = CCA_WARNING (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.)"), errorStr)
我對你正在尋找的東西做了一堆假設,但這可能會有所幫助
uj5u.com熱心網友回復:
我不太確定您是希望輸出是訊息字串還是希望將決議的資訊作為物件陣列,因此在下面,它同時執行:
$matchFound = @"
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;
"@ -split '\r?\n'
$inCase = $false # a flag telling us if we're inside a 'case' or not
$result = switch -Regex ($matchFound) {
'^\s*case kRESULT' {
$inCase = $true
# create an object with for now null values in its properties
$out = [PsCustomObject]@{ sdkErr = $nul; sdkDesc = $null; sdkSeverity = $null }
}
'^\s*_stprintf\(\s*outDevStr, _T\("(\d ) - (\(. \))"' {
if ($inCase) {
$out.sdkErr = $matches[1]
$out.sdkDesc = $matches[2]
}
}
'^\s*outSeverity = (\w )' {
if ($inCase) {
$out.sdkSeverity = ($matches[1] -split '_')[-1]
# now we have all info, output a string to the console
Write-Host ('sdkErr: {0}, sdkDesc: {1}, sdkSeverity: {2}' -f $out.sdkErr, $out.sdkDesc, $out.sdkSeverity)
# and output the completed object to be collected in $result
$out
# reset the flag so we can rebuild the object for the next 'case kRESULT'
$inCase = $false
}
}
}
寫在螢屏上的輸出:
sdkErr: 8004, sdkDesc: (Comm. Err 04) - %s(Undefined Opcode), sdkSeverity: WARNING
sdkErr: 8005, sdkDesc: (Comm. Err 05) - %s(Timeout sending command), sdkSeverity: WARNING
sdkErr: 8006, sdkDesc: (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.), sdkSeverity: WARNING
在變數中捕獲的輸出$result:
$result | Format-Table -AutoSize
sdkErr sdkDesc sdkSeverity
------ ------- -----------
8004 (Comm. Err 04) - %s(Undefined Opcode) WARNING
8005 (Comm. Err 05) - %s(Timeout sending command) WARNING
8006 (Comm. Err 06) - %s(TXD Failed--Send buffer overflow.) WARNING
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/381804.html
標籤:regex powershell
