Search code examples
powershell

find and replace special characters powershell


I have a method that has an if statement that catches if it finds a special character. What I want to do now if find the position of the special characters and replace it with _A

Some Examples

  • test# becomes test_A

  • I#hope#someone#knows#the#answer# becomes I_Ahope_Asomeone_Aknows_Athe_Aanswer_A

or if it has more than one special character

  • You?didnt#understand{my?Question# becomes You_Adidnt_Aunderstand_Amy_AQuestion_A

Would I have to loop through the whole string and when I reach that character change it to _A or is there a quicker way of doing this?


Solution

  • # is just a character like any other, you can use the -replace operator:

    PS C:\>'I#hope#someone#knows#the#answer#' -replace '#','_A'
    I_Ahope_Asomeone_Aknows_Athe_Aanswer_A
    

    Regex is magic, you can define all the special cases you like (braces will have to be escaped):

    PS C:\>'You?didnt#understand{my?Question#' -replace '[#?\{]','_A'
    You_Adidnt_Aunderstand_Amy_AQuestion_A
    

    So your function could look something like this:

    function Replace-SpecialChars {
        param($InputString)
    
        $SpecialChars = '[#?\{\[\(\)\]\}]'
        $Replacement  = '_A'
    
        $InputString -replace $SpecialChars,$Replacement
    }
    
    Replace-SpecialChars -InputString 'You?didnt#write{a]very[good?Question#'
    

    If you are unsure of which characters to escape, have the regex class do it for you!

    function Replace-SpecialChars {
        param(
            [string]$InputString,
            [string]$Replacement  = "_A",
            [string]$SpecialChars = "#?()[]{}"
        )
    
        $rePattern = ($SpecialChars.ToCharArray() |ForEach-Object { [regex]::Escape($_) }) -join "|"
    
        $InputString -replace $rePattern,$Replacement
    }
    

    Alternatively, you can use the .NET string method Replace():

    'You?didnt#understand{my?Question#'.Replace('#','_A').Replace('?','_A').Replace('{','_A')
    

    But I feel the regex way is more concise