3

As with in the self-answer, I like to be able to remove control characters from text to get a single line string.
Does there exists a PowerShell Escape function for Special PowerShell Characters?
(Similar to the Regex.Escape(String) Method for escaping special regex characters)
Or is there a smarter way to do this than the self-answer?
(I am less concerned with the Unicode escape sequence: `u{x})

iRon
  • 20,463
  • 10
  • 53
  • 79

4 Answers4

3

Using a regular expression callback:

$Backtick = @{}
foreach ($Char in '0abefnrtv`'.ToCharArray()) {
    $Backtick[$ExecutionContext.InvokeCommand.ExpandString("``$Char")] = "``$Char"
}
$SpecialCharacters = '[' + (-Join $Backtick.get_Keys()) + ']'
function Escape($Text) {
    [regex]::Replace($Text, $SpecialCharacters, { param($Match) $Backtick[$Match.Value] })
}

Escape 'Test
123'

Test`n123
iRon
  • 20,463
  • 10
  • 53
  • 79
2

Not as good as your code, but here's an alternative way:

function Escape([string]$Text) {
    if (![string]::IsNullOrWhiteSpace($Text)) { 
        $special = 0,7,8,9,10,11,12,13,27,96 | ForEach-Object { [char]$_ }
        $escaped = '`0', '`a', '`b', '`t', '`n', '`v', '`f', '`r', '`e', '`'
        0..($special.Count -1) | ForEach-Object { $Text = $Text -replace $special[$_], $escaped[$_] }
    }
    $Text
}
Escape 'Test
123'

# --> Test`r`n123
mklement0
  • 382,024
  • 64
  • 607
  • 775
Theo
  • 57,719
  • 8
  • 24
  • 41
2

To offer a prepackaged solution based on the Debug-String function, available as an MIT-licensed Gist:

Assuming you have looked at the linked code to ensure that it is safe (which I can personally assure you of, but you should always check), you can install it directly as follows:

irm https://gist.github.com/mklement0/7f2f1e13ac9c2afaf0a0906d08b392d1/raw/Debug-String.ps1 | iex

The primary purpose of Debug-String is to visualize (hidden) control characters and spaces in strings (see this answer), but it also offers the -AsSourceCode and -SingleLine switches, which produce the desired single-line, control-characters-as-escape-sequences string representations (albeit with the enclosing " chars., but you can easily trim them with .Trim('"').

Additionally, you may use -UnicodeEscapes in order to represent non-ASCII-range characters (e.g. é) by their Unicode escape sequences (e.g. `u{e9}), though note that such escapes are only recognized in PowerShell (Core) v6+.

Debug-String -AsSourceCode -SingleLine -UnicodeEscapes 'Tést`1
123'

The above yields (verbatim, including the " chars.), which can be copied and pasted into PowerShell code to expand to the original string:

"T`u{e9}st``1`n123"
mklement0
  • 382,024
  • 64
  • 607
  • 775
0

To build on the answer by iRon, this version excludes 'e' if the powershell version is below 6. (It also puts the variables inside of the function because the code I'm using it for deals with the names of global variables returned by Get-Variable.)

function PSEscape($Text) {

    $Backtick = @{}
    foreach ($Char in ((@('','e')[$PSVersionTable.PSVersion.Major -ge 6])+'0abfnrtv`').ToCharArray()) {
        $Backtick[$ExecutionContext.InvokeCommand.ExpandString("``$Char")] = "``$Char"
    }
    $SpecialCharacters = '[' + (-Join $Backtick.get_Keys()) + ']'

    [regex]::Replace($Text, $SpecialCharacters, { param($Match) $Backtick[$Match.Value] })
}