Powershell: Doubled double quotes in inline expressions

与世无争的帅哥 提交于 2019-12-24 02:06:08

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!