Using the replace operator on a string that has quotes powershell - powershell

I am looking to run the command
foreach-object {$_ -replace
However the string I am attempting to work with could be described as the follow
this string "has" quotes
the whole line being
foreach-object {$_ -replace "this string "has" quotes", "this string "won't have" quotes"}
How do I make this quote filled line work with powershell?

You can either escape the nested double quotes like so `" or better yet, use single quotes for quoting of the string then you won't need to escape the double quotes e.g.:
'this string "has" quotes'
Note: with single quotes you won't get variable expansion in a string.

You can Grave (the tilde key) double quotation marks as an escape character. You can do this to any special character in a string.
e.g.
$a = "This String `"Has`" Quotes"
$a = $a.replace("This String `"Has`" Quotes","this string won't have quotes. ")

Related

add quotation mark to a text file powershell

I need to add the quotation mark to a text file that contains 500 lines text.
The format is inconsistent. It has dashes, dots, numbers, and letters. For example
1527c705-839a-4832-9118-54d4Bd6a0c89
16575getfireshot.com.FireShotCaptureWebpageScreens
3EA2211E.GestetnerDriverUtility
I have tried to code this
$Flist = Get-Content "$home\$user\appfiles\out.txt"
$Flist | %{$_ -replace '^(.*?)', '"'}
I got the result which only added to the beginning of a line.
"Microsoft.WinJS.2.0
The expected result should be
"Microsoft.WinJS.2.0"
How to add quotation-mark to the end of each line as well?
There is no strict need to use a regex (regular expression) in your case (requires PSv4+):
(Get-Content $home\$user\appfiles\out.txt).ForEach({ '"{0}"' -f $_ })
Array method .ForEach() processes each input line via the script block ({ ... }) passed to it.
'"{0}"' -f $_ effectively encloses each input line ($_) in double quotes, via -f, the string-format operator.
If you did want to use a regex:
(Get-Content $home\$user\appfiles\out.txt) -replace '^|$', '"'
Regex ^|$ matches both the start (^) and the end ($) of the input string and replaces both with a " char., effectively enclosing the input string in double quotes.
As for what you tried:
^(.*?)
just matches the very start of the string (^), and nothing else, given that .*? - due to using the non-greedy duplication symbol ? - matches nothing else.
Therefore, replacing what matched with " only placed a " at the start of the input string, not also at the end.
You can use regex to match both:
The beginning of the line ^(.*?)
OR |
The End of the line $
I.e. ^(.*?)|$
$Flist = Get-Content "$home\$user\appfiles\out.txt"
$Flist | %{$_ -replace '^(.*?)|$', '"'}

To check for special characters in a string

I need to find special character in a string which has alphanumeric values in it.
I have tried the below code snippet but it doesn't work.
$Special_characters = ('\n|\r|\t|\a|\"|\`')
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
if($Value -match $Special_characters)
{
Write-Host "Special characters are present"
}
else
{
Write-Host "special characters are absent"
}
The output says "special characters are absent" even though there are special characters at the end. How to resolve it?
$Special_Characters here is a string, so your code is searching for the whole word (\n|\r|\t|\a|\"|`) to be found in $Value, which is not found.
Instead of string, you have to use array as follows:
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
$Special_Characters = #('\\n','\\r','\\t','\\a','\\"','\\`')
$Special_Characters | Foreach-Object {
if ($Value -match $_) {
"$_ is present"
} else {
"$_ is not present"
}
}
Note
You have to put double back-slash (\\) because backslash is considered as escape character in Powershell; Look here for further information about backslash in Powershell
There is a misunderstanding here.
The backslash is used to define a special character in a Regular Expression, as e.g. \t define a tab.
But this is not the case for PowerShell. To define a special character in PowerShell you need to use the backtick character (See: About Special Characters), e.g. a Tab is written as `t.
In other words, the regular expression pattern in the question is correct but the input string is not (in contrast to what the question/title suggests, there is in fact no special character in the given input string").
it should be:
"...hs9sn329hs`t" -match '\n|\r|\t|\a|\"|\`'
True
As it concerns a list of single (special) characters, you might also consider a bracket expression (rather than an OR "pipe" character) for this:
"...hs9sn329hs`t" -match '[\n\r\t\a\"\`]'
True
Visa versa: it is allowed to use special characters in a regular expression pattern using double quotes so that PowerShell will evaluate the string (but I recommend against this):
"...hs9sn329hs`t" -match "`n|`r|`t|`a|`"|``"
True
If the input string in the question is really the string you want to check upon (implying that you refer to the backslash as a special character, which formally is not), you want to check for a \t rather than a tab,. For this you will need to escape the backslashes in your regular expression to literally match the \t:
"...hs9sn329hs\t" -match '\\n|\\r|\\t|\\a|\\"|\\`'
True
Its an one-liner:
$Special_characters = '\n|\r|\t|\a|\"|\`'
$Value = "g63evsy3swisnwhd83bs3hs9sn329hs\t"
$result = #($Special_characters -split '\|' | % { $Value.Contains( $_ ) }).Contains( $true )
$result is true when a special character is found, otherwise false.
Here's all the special characters you referred to. You can try out a string by itself just to see if it works. It must be double quoted.
PS /Users/js> "`n`r`t`a`"``"
"`
You can also try out the -match operator by itself.
PS /Users/js> "`n`r`t`a`"``" -match '\n|\r|\t|\a|\"|\`'
True
About special characters: https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters?view=powershell-6

Regex pattern with embedded double quotes in PowerShell

Following keyword need to be searched on document using PowerShell:
["Allowed Acquisition Clean-Up Period"
$keyword = ""
Get-Content $SourceFileName | Select-String -Pattern $keyword
String which I'm searching for has double quotes in it, so I'm struggling how to mention in this $keyword.
Apparently you not only have double quotes, but also an opening square bracket. Square brackets are meta-characters in regular expressions (for defining character classes), so you need to escape those too.
Define your expression in single quotes:
$keyword = '\["Allowed Acquisition Clean-Up Period"'
or escape nested double quotes with backticks:
$keyword = "\[`"Allowed Acquisition Clean-Up Period`""
To complement Ansgar Wiechers' helpful answer, which contains the correct solution:
Given that " is not a regex metacharacter (has no special meaning in a regular expression), your question boils down to:
How can I embed a " (double quote) in a string in PowerShell?.
As an aside: As stated, [ is a regex metacharacter, so it must be escaped as \[ inside a regex in order to be treated as a literal. As TheIncorrigible1 points out, you can let [regex]::Escape($string) handle that escaping for you; the result treats the content of $string literally in the context of a regex.
There are several options, demonstrated here with a simplified sample string, 3 " of rain - see also: Get-Help about_Quoting_Rules:
# Inside a *literal string* ('...'):
# The content of single-quoted strings is treated *literally*.
# Double quotes can be embedded as-is.
'3 " of rain'
# Inside an *expandable string* ("..."):
# Such double-quoted strings are subject to *expansion* (interpolation)
# of embedded variable references ("$var") and expressions ("$(Get-Date)")
# Use `" inside double quotes; ` is PowerShell's escape character.
"3 `" of rain" #"
# Inside "...", "" works too.
"3 "" of rain"
# Inside a *literal here-string* (multiline; end delimiter MUST be
# at the very beginning of a line):
# " can be embedded as-is.
#'
3 " of rain
'#
# Inside an *expanding here-string*:
# " can be embedded as-is, too.
#"
3 " of rain
"#
For the sake of completeness: you can create a double quote via its Unicode code point (the number that identifies each character), which is 0x22 (hex) / 34 (decimal), by casting it to [char], e.g.: [char] 0x22.
You can use this:
in string concatenations: '3 ' + [char] 0x22 + ' of rain'
in string-formatting expressions with the -f operator: '3 {0} of rain' -f [char] 0x22

Find and replace a string containing both double quotes and brackets

Let's say I have a test file named testfile.txt containing the below line:
one (two) "three"
I want to use PowerShell to say that if the entire string exists, place a line directly underneath it with the value:
four (five) "six"
(Notice that it includes both spaces, brackets and double quotes. This is important, as the problem I am having is I think with escaping the brackets and double quotes).
So the result would be:
one (two) "three"
four (five) "six"
I thought the easiest way of doing it would be to say that if the first string is found, replace it with the first string itself again, and the new string forming a new line included in the same command. I had difficulty putting the strings in line so I tried using a herestring variable whereby an entire text block with formatting is read. It still does not parse the full string with quotes into the pipeline. I'm new to powershell so don't hold back if you see something stupid.
$herestring1 = #"
one (two) "three"
"#
$herestring2 = #"
one (two) "three"
four (five) "six"
"#
if((Get-Content testfile.txt) | select-string $herestring1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $herestring1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}
The above just gives "No match found" every time. This is because it does not find the first string in the file.
I have tried variations using backtick [ ` ] and doubling quotes to try to escape, but I thought the point in a here string was that it should parse the text block including all formatting so I should not have to.
If I change the file to contain only:
one two three
and then change the herestring accordingly to:
$herestring1 = #"
one two three
"#
$herestring2 = #"
one two three
four five six
"#
Then it works ok and I get the string replaced as I want.
As Martin points out, you can use -SimpleMatch with Select-String to avoid parsing it as a regular expression.
But -replace will still be using a regex.
You can escape the pattern for RegEx using [RegEx]::Escape():
$herestring1 = #"
one (two) "three"
"#
$herestring2 = #"
one (two) "three"
four (five) "six"
"#
$pattern1 = [RegEx]::Escape($herestring1)
if((Get-Content testfile.txt) | select-string $pattern1) {
"Match found - replacing string"
(Get-Content testfile.txt) | ForEach-Object { $_ -replace $pattern1,$herestring2 } | Set-Content ./testfile.txt
"Replaced string successfully"
}
else {
"No match found"}
Regular expressions interpret parentheses () (what you are calling brackets) as special. By default, spaces are not special, but they can be with certain regex options. Double quotes are no problem.
In regex, the escape character is backslash \, and this is independent of any escaping you do for the PowerShell parser using backtick `.
[RegEx]::Escape() will ensure anything special to regex is escaped so that a regex pattern will interpret it as literal, so your pattern will end up looking like this: one\ \(two\)\ "three"
Just use the Select-String cmdlet with the -SimpleMatch switch:
# ....
if((Get-Content testfile.txt) | select-string -SimpleMatch $herestring1) {
# ....
-SimpleMatch
Indicates that the cmdlet uses a simple match rather than a regular
expression match. In a simple match, Select-String searches the input
for the text in the Pattern parameter. It does not interpret the value
of the Pattern parameter as a regular expression statement.
Source.

how to replace string using powershell

I have the following string: $str = '"FirstName":"first name","LastName":"Last name","AskCatalog":false,"Nuteres":61","ZipCode":"1234"'
and I need to replace value of ,for example, FirstName:"first name" with a variable like this
"FirstName":"$strFristname"
Can anyone show me how can I do that in PowerShell?
Thank you.
Like this:
$str -replace '("FirstName":)".*?"', "`$1`"$strFirstname`""
The pattern ("FirstName":)".*?" matches the string "FirstName": followed by a double quote and the shortest match of any character (.*?) up to the next double quote. The parentheses create a group that can be referenced by $1 in the replacement string. Due to the double quotes around the replacement string that reference must be escaped (`$1). The same goes for the nested double quotes (`").
If you want the variable instead of its value to show up in the result, you need to escape the $ of the variable as well:
$str -replace '("FirstName":)".*?"', "`$1`"`$strFirstname`""
Demonstration:
PS C:\> $str = '"FirstName":"first name","LastName":"Last name"'
PS C:\> $strFirstname = 'Joe'
PS C:\> $str -replace '("FirstName":)".*?"', "`$1`"$strFirstname`""
"FirstName":"Joe","LastName":"Last name"
PS C:\> $str -replace '("FirstName":)".*?"', "`$1`"`$strFirstname`""
"FirstName":"$strFirstname","LastName":"Last name"