2

I'm trying to analyse lots of powershell scripts in a number of directories and i want to pull any Catch code blocks into a list/ variable.

I'm trying to write a regex to select any block in the following formats

    Catch 
        {
        write-Host "Function:",$MyInvocation.MyCommand,"Failed with exception:" "Error"
        write-Host "Exception: $_" "Error"
        throw "Exception: $_"
        }

    Catch{
        write-Host "Function:",$MyInvocation.MyCommand,"Failed with exception:" "Error"
        write-Host "Exception: $_" "Error"
        throw "Exception: $_" }
Catch {write-Host "Function:",$MyInvocation.MyCommand,"Failed with exception:" "Error"
        write-Host "Exception: $_" "Error"
        throw "Exception: $_"}

Essentially anywhere there is a catch followed by {}, ignoring any line breaks between the word "Catch" and the braces and after the braces, ignoring case.

I want the entire contents between the {} returned too so i can do some additional checks on it.

The best i have managed to come up with is:


\b(\w*Catch\w*)\b.*\w*{\w.*}

Which will match if its all on one line.

I'll be doing this in powershell so .net or powershell type regex would be appreciated.

Thanks.

2 Answers 2

5

Don't use regex to parse PowerShell code in PowerShell

Use the PowerShell parser instead!

foreach($file in Get-ChildItem *.ps1){
    $ScriptAST = [System.Management.Automation.Language.Parser]::ParseFile($file.FullName, [ref]$null, [ref]$null)

    $AllCatchBlocks = $ScriptAST.FindAll({param($Ast) $Ast -is [System.Management.Automation.Language.CatchClauseAst]}, $true)

    foreach($catch in $AllCatchBlocks){
        # The catch body that you're trying to capture
        $catch.Body.Extent.Text

        # The "Extent" property also holds metadata like the line number and caret index
        $catch.Body.Extent.StartLineNumber
    }
}
Sign up to request clarification or add additional context in comments.

Comments

2

My guess is that you wish to capture catch with this expression or something similar to:

\s*\bCatch\b\s*({[\s\S]*?})

that collects new lines.

Demo

and if the word boundary is not required:

\s*Catch\s*({[\s\S]*?})

1 Comment

This is a perfect answer to my question, thank you. However Mathias response was more suited to me aim

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.