Replace particulars characters in powershell - regex

I am trying to replace a character to escape it in a Powershell string to convert it to JSON later. I would like to replace the double quotes " in the cmdline by a single quote followed by a double quotes, to escape the double quotes.
I have this string : user123" -a.exe
I would like to have user123'" -a.exe
I try different combinations with the -replace function like
$test -replace '"',''"'
but no one works due to the particularity of these characters.
Thanks in advance for your help

To force Windows PowerShell to interpret a double quotation mark literally, use a backtick(`) character.
PS C:\> $test = "user123`" -a.exe"
PS C:\> $test
user123" -a.exe
PS C:\> $test = $test -replace "`"","'`""
PS C:\> $test
user123'" -a.exe
To learn most of the variations and tricks to work with Quotes, type
Help about_Quoting_Rules
at Powershell console.

You need to use backtick(`) character to escape special characters and use String.Replace method
$test = "user123`" -a.exe"
$test.replace("`"","`'`"")
Result:
user123'" -a.exe

If you're dealing with a manipulating quoted text, and find the escaping rules are confusing and/or result in obfuscated code, you can also deal with it as here-strings. Within the here-string delimiters (#'-'#) normal quoting rules don't apply. It can make for longer code, but may be more intuitive to read and debug or do maintenance on later.
$string = #'
user123" -a.exe
'#
$match = #'
"
'#
$replace = #'
"'
'#
$string.replace($match,$replace)
user123"' -a.exe
This is obviously a trivial example, but as the amount of quoted text and increases so will the advantage of using the here-strings over constructing arguments inline using escaped characters.

Related

How do you use a variable in a regex replace statement [duplicate]

$file = 'c:\temp\config.ini'
# login.ruby.authentication.key=eskimopie
$pattern = [regex] "(.*?login\.ruby\.authentication\.key)=(.*?).*"
$secret = '12345678'
$text = (Get-Content -Path c:\temp\config.ini)
$value = $text -match "$pattern"
$text -replace "$pattern",'$1=$secret' | Set-Content config.new
The problem is it replaces the line with
login.ruby.authentication.key)=$secret (in that, it actually puts $secret instead of 12345678. I am looking for how to get this to put the value of $secret instead of the word $secret.
When used inside single quoted literals, variables do not get expanded. You need to use double quoted string literal that allows string interpolation.
However, the first $ should not be expanded. To tell PS not to interpolate it, add a backtick before it. See about_Quoting_Rules:
To prevent the substitution of a variable value in a double-quoted string, use the backtick character (`)(ASCII 96), which is the Windows PowerShell escape character.
So, replace with "`$1=$secret" where `$1 will pass a literal $1 string to the regex engine, and $secret will get interpolated to 12345678 before passing it to the regex engine.

Powershell - How to replace a number with a variable in a string?

Trying to replace a number (20 with a variable $cntr=120) in a string using replace operator. But getting stuck with $cntr in the output. Where I am doing wrong? Any better solutions please.
Input string
myurl.com/search?project=ABC&startAt=**20**&maxResults=100&expand=log
Desired Output string
myurl.com/search?project=ABC&startAt=**120**&maxResults=100&expand=log
Actual Output string
myurl.com/search?project=ABC&startAt=**$cntr**&maxResults=100&expand=log
Code:
$str='myurl.com/search?project=ABC&startAt=20&maxResults=100&expand=log'
$cntr=120
$str = $str -replace '^(.+&startAt=)(\d+)(&.+)$', '$1$cntr$3'
$str
You need to
Use double quotes to be able to use string interpolation
Use the unambiguous backreference syntax, ${n}, where n is the group ID.
In this case, you can use
PS C:\Users\admin> $str='myurl.com/search?project=ABC&startAt=20&maxResults=100&expand=log'
PS C:\Users\admin> $cntr=120
PS C:\Users\admin> $str = $str -replace '^(.+&startAt=)(\d+)(&.+)$', "`${1}$cntr`$3"
PS C:\Users\admin> $str
myurl.com/search?project=ABC&startAt=120&maxResults=100&expand=log
See the .NET regex "Substituting a Numbered Group" documentation:
All digits that follow $ are interpreted as belonging to the number group. If this is not your intent, you can substitute a named group instead. For example, you can use the replacement string ${1}1 instead of $11 to define the replacement string as the value of the first captured group along with the number "1".
A couple things here:
If you just add the "12" you end up with $112$3 which isn't what you want. What I did was appended a slash in front and then removed it on the backend, so the replace becomes $1\12$3.
$str='myurl.com/search?project=ABC&startAt=20&maxResults=100&expand=log'
$cntr=12
$str = ($str -replace '^(.+&startAt=)(\d+)(&.+)$', ('$1\' + $cntr.ToString() +'$3')).Replace("\", "")
$str
Looking to see if there's another way to add the literal "12" in the replace section with the extra character, but this does work.
Here's another way to do it where you have a literal string between the $1 and $3 and then replace that at the end.
$str='myurl.com/search?project=ABC&startAt=20&maxResults=100&expand=log'
$cntr=12
$str = ($str -replace '^(.+&startAt=)(\d+)(&.+)$', ('$1REPLACECOUNTER$3')).Replace("REPLACECOUNTER", "$cntr")
$str

Powershell variable in replacement string with named groups

The following Powershell replace operation with named groups s1 and s2 in regex (just for illustration, not a correct syntax) works fine :
$s -Replace "(?<s1>....)(?<s2>...)" '${s2}xxx${s1}'
My question is : how to replace with a variable $x instead of the literal xxx, that is, something like :
$s -Replace "(?<s1>....)(?<s2>...) '${s2}$x${s1}'
That doesn't work as Powershell doesn't replace variable in single quoted string but the named group resolution doesn't work anymore if replacement string is put in double quotes like this "${s2}$x${s1}".
#PetSerAl comment is correct, here is code to test it:
$sep = ","
"AAA BBB" -Replace '(?<A>\w+)\s+(?<B>\w+)',"`${A}$sep`${B}"
Output:
AAA,BBB
Explanation:
Powershell will evaluate the double quoted string, escaping the $ sign with a back tick will ensure these are not evaluated and a valid string is provided for the -Replace operator.
msdn about replace operator
msdn about escape characters
or via Get-Help about_escape & Get-Help about_comparison_operators

How to use $_ in content without been replaced by powershell?

I'm trying to replace a word to some php code
$filecontent = [regex]::Replace($filecontent, $myword, $phpcode)
But the $phpcode have some php code using also a Special variable $_
<?php $cur_author = (isset($_GET['author_name'])) ? get_user_by('slug', $author_name) : get_userdata(intval($author)); ?>
The problem is when the code is replace in $filecontent it replaces the $_ variable from the php code ( $_GET ) with it have on the pipeline.
This not happen with the other variables like $author_name .
How can I resolve this?
Does this work for you?
$filecontent = [regex]::Replace($filecontent, $myword, {$phpcode})
In a regex replace operation the $_ is a reserved substituion pattern that represents the entire string
http://msdn.microsoft.com/en-us/library/az24scfc.aspx
Wrapping it in braces makes it a scriptblock delegate, bypassing the normal regex pattern matching algorithms for doing the replacement.
You have two options. First use a single quoted string and PowerShell will treat that as a verbatim string (C# term) i.e. it won't try to string interpolate:
'$_ is passed through without interpretation'
The other option is to escape the $ character in a double quoted string:
"`$_ is passed through without interpretation"
When I'm messing with a regex I will default to using single quoted strings unless I have a variable that needs to be interpolated inside the string.
Another possibility is that $_ is being interpreted by regex as a substitution group in which case you need to use the substitution escape on the $ e.g. $$.
Im not sure I am following you correctly, but does this help?
$file = path to your file
$oldword = the word you want to replace
$newword = the word you want to replace it with
If the Oldword you are replacing has special charactes ( ie. \ or $ ) then you must escape them first. You can escape them by putting a backslash in front of the special character. The Newword, does not need to be escaped. A $ would become "\$".
(get-content $file) | foreach-object {$_ -replace $oldword,$NewWord} | Set-Content $file

Powershell - Replacing a string with a variable ending with a dollar sign

I'm a bit lost with this one. For whatever reason the replace function in powershell doesn't play well with variables ending with a $ sign.
Command:
$var='A#$A#$'
$line=('$var='+"'"+"'")
$line -replace '^.+$',('$line='+"'"+$var+"'")
Expected output:
$line='A#$A#$'
Actual output:
$line='A#$A#
It looks like you're getting hit with a regex substitution that you don't want. The regex special variable $' represents everything after your match. Since your regex matches the entire string, $' is effectively empty. During the replace operation, the .Net regex engine sees $' in your expected output and substitutes in that empty string.
One way to avoid this is to replace all instances of $ in your $var string with $$:
$line -replace '^.+$',('$line='+"'"+($var.Replace('$','$$'))+"'")
You can see more information about regex substitution in .Net here:
Substitutions
I was able to find a band-aid of sorts by replacing $ with a special character and then reverting it back after the change. Preferably you would choose a character that doesn't have a key on your keyboard. For me I chose "¤".
$var='A#$A#$'
$var=$var -replace '\$','¤'
$line=("`$var=''")
$line -replace '^.+$',("`$line='$var'") -replace '¤','$'
I don't really understand the purpose of your posted lines, it seems to me that it would just make more sense to do $line='$line='''+$var+"'", BUT if you insist on your way, just do two replace calls, like this:
$line -replace '^.+$',('$line=''LOL''') -replace 'LOL',$var