Regex pattern with embedded double quotes in PowerShell - 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

Related

Slack block markdown syntax not working in hashtable

I'm generating a Slack message using a hashtable in Powershell.
Here is how the hashtable is generated:
$serviceitems = foreach ($r in $rows) {
#{
type = 'section'
text = #{
type = 'mrkdwn'
text = "*{0}*\n{1:C2}" -f $r[1], $r[0]
}
}
#{
type = 'divider'
}
}
The messsages show up in Slack but the \n prints out instead of going to a new line like it should. The two * make the text bold as intended. I tried adding a backtick to before \n and also tried adding an extra \. Both made no change.
\ has no special meaning in PowerShell strings.
PowerShell uses ` (the so-called backtick) as the escape character, so you need escape sequence `n inside an expandable (double-quoted) string ("...") in order to embed an actual newline (LF character) in the strings.
Simple example:
PS> "line 1`nline 2" | ForEach-Object { "[$_]" }
[line 1
line 2]
PowerShell happily accepts LF alone as a newline; if you do need CRLF newlines, use `r`n. To refer to the platform-native newline sequence, use [Environment]::NewLine ($([Environment]::NewLine) to use it inside "...").
See also:
The conceptual about_Special_Characters help topic.
As for what you tried:
I tried adding a backtick to before \n and also tried adding an extra \.
As implied at the top, \ should not be in the picture at all.
Trying `\n results in ` escaping the \ character, which has no effect (escaping a non-special character is ignored); in other words: "`\n" is the same as "\n" which is verbatim \n

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 '^(.*?)|$', '"'}

How to -replace continuous special characters?

In PowerShell when trying to replace
"Columnname1||colunnname2||kjhsadjhj|kjsad" -replace "[||]", "','"
above command is doing
"Columnname1','','colunnname2','','kjhsadjhj','kjsad"
but I'd like to replace the exact match like below
"Columnname1','colunnname2','kjhsadjhj|kjsad"
Your code doesn't do what you want because your search pattern defines a character class. Square brackets in a regular expression will match exactly one occurrence of any of the enclosed characters, even if you specify a character multiple times. [||] will thus match exatly one | character.
Since you apparently don't actually want to use a regular expression match I'd recommend doing a normal string replacement via the Replace() method rather than a regular expression replacement via the -replace operator:
"Columnname1||colunnname2||kjhsadjhj|kjsad".Replace('||', "','")
If you want to stick with a regular expression replacement you must specify two literal | characters, either by escaping them, as PetSerAl suggested
"Columnname1||colunnname2||kjhsadjhj|kjsad" -replace '\|\|', "','"
or by putting each of them in its own character class
"Columnname1||colunnname2||kjhsadjhj|kjsad" -replace '[|][|]', "','"
The regex pattern [||] means "1 of | or one of |"
Change it to \|{2} to match two consecutive pipes:
"Columnname1||colunnname2||kjhsadjhj|kjsad" -replace "\|{2}", "','"
Just in case your end result should be:
'Columnname1','colunnname2','kjhsadjhj|kjsad'
$string = '"Columnname1||colunnname2||kjhsadjhj|kjsad"'
$string
$String = $string -replace '^"|"$',"'" -replace '\|{2}',"','"
$string
Sample output:
"Columnname1||colunnname2||kjhsadjhj|kjsad"
'Columnname1','colunnname2','kjhsadjhj|kjsad'

How do I escape curly braces {...} in powershell?

I need to generate multiple lines of xml tag with a GUID in them:
<xmltag_10 value="{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}"/>
<xmltag_11 value="{ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ}"/>
and so on
I have this line in a loop where $guid is generated each iteration, and it prints the guid without surrounding braces
Write-Host ('<xmltag_{0} value="{1}"/>' -f $i,$guid)
<xmltag_10 value="ZZZZZZZZ-ZZZZ-ZZZZ-ZZZZ-ZZZZZZZZZZZZ"/>
Adding a set of curly braces, I get
Write-Host ('<xmltag_{0} value="{{1}}"/>' -f $i,$guid)
<xmltag_10 value="{1}"/>
How do I escape the outer curly braces? I've tried using `{{1}`} to escape but I get
Error formatting a string: Input string was not in a correct format..
Adding my code for copying and testing:
$i=10
while($i -lt 21)
{
$guid = ([guid]::NewGuid()).ToString().ToUpper();
Write-Host ('<xmltag_{0} value="{1}"/>' -f $i,$guid)
$i++
}
To escape curly braces, simply double them:
'{0}, {{1}}, {{{2}}}' -f 'zero', 'one', 'two'
# outputs:
# zero, {1}, {two}
# i.e.
# - {0} is replaced by zero because of normal substitution rules
# - {{1}} is not replaced, as we've escaped/doubled the brackets
# - {2} is replaced by two, but the doubled brackets surrounding {2}
# are escaped so are included in the output resulting in {two}
So you could to this:
Write-Host ('<xmltag_{0} value="{{{1}}}"/>' -f $i,$guid)
However; in your scenario you don't need to use -f; it's a poor fit if you need to use literal curly braces. Try this:
$i=10
while($i -lt 21)
{
$guid = ([guid]::NewGuid()).ToString().ToUpper();
Write-Host "<xmltag_$i value=`"$guid`"/>"
$i++
}
This uses regular variable substitution in a double quoted string (but it does require escaping the double quotes using `" (the backtick is the escape character).
Another option would have been to use a format specifier. i.e. Format B causes a GUID to be surrounded by braces. Sadly it also formats the GUID in lowercase, so if the case of the output is part of your requirement, this would not be appropriate.
Write-Host ('<xmltag_{0} value="{1:B}"/>' -f $i, $guid)

Using the replace operator on a string that has quotes 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. ")