问题
Please could anyone explain me why the following happens:
"Fancy string - Hor""ray"
# outputs correctly (only one double quote): Fancy string - Hor"ray
'Hor"ray'.Replace('"', '""')
# outputs correctly (two double quotes): Hor""ray
"Fancy string - $('Hor"ray'.Replace('"', '"'+'"'))"
#outputs correctly (two double quotes): Hor""ray
"Fancy string - $('Hor"ray'.Replace('"', '""'))"
# outputs INCORRECTLY (only one double quote): Fancy string - Hor"ray
In my opinion, developers would intuitively expect, that within "$(inline expressions)" Powershell would treat text as statements and won't interfere with the last argument of Replace('"', '""')
converting it into '"'
(unless the statement interpreter decides to do so).
Do I miss something here?
回答1:
This appears to be a bug in how PowerShell parses expandable string literals.
From §2.3.5.2 on string literals in the PowerShell 3.0 Language Specification, the expandable-string-literal explicitly rejects the $(
sequence so that sub-expression parsing will occur instead.
So it seems reasonable to expect $('""')
to parse consistently, whether or not it happens to be embedded in a string literal. And clearly sub-expressions are parsed separately, since they support values that would be illegal on their own in an expandable string (e.g. you can write "$('"')"
or "$('`""')"
, where " '"' "
or " '`""' "
would fail).
However, comparing the AST from [Management.Automation.Language.Parser]::ParseInput for both $('""')
and "$('""')"
, we get two different results. Both have a final StringConstantExpressionAst
element with an Extent
of '""'
, but the Value
for the stand-alone sub-expression is ""
while the Value
for the embedded sub-expression is "
.
回答2:
Its because the inline expression is evaluated and its string value is then placed in the string and evaluated.
#Breaking "Fancy string - $('Hor"ray'.Replace('"', '""'))" down
#This inline expression is evaluated first
$('Hor"ray'.Replace('"', '""'))
#giving
Hor""ray
#That value is then interpreted as part of the string
"Fancy string - Hor""ray"
#giving
Fancy string - Hor"ray
This is exactly what I would expect to see. The inline expression evaluated and its resulting value then being used.
回答3:
Could this not be done by simply using things like below:
`'$($RemFiles[$i].FullName)`'
`"$($RemFiles[$i].FullName)`"
Use the backtick and either a single or double quote to then prevent powershell from using this as an open comment, thus putting the actual symbol in...
The above outputs:
'F:\portable\adobe'
or
"F:\portable\adobe"
I noticed that it seems you are telling it to literally add two double quotes rather than just using the backtick to force it. Therefore telling it to add nothing surely :S So could you change this to something like this:
"Fancy string - $('Hor"ray'.Replace('"', '`"`"'))"
Though that may make 3, as you have one present in Hor"ray anyway.
Just got to test it, was busy with something:
PS D:\> "Fancy string - $('Hor"ray'.Replace('"', '`"`"'))"
Fancy string - Hor""ray
Scroll down on the site below to find out about the backtick and how/where it can be used.
http://www.neolisk.com/techblog/powershell-specialcharactersandtokens
来源:https://stackoverflow.com/questions/24242338/powershell-doubled-double-quotes-in-inline-expressions