嵌套在此处的PowerShell字符串

嵌套在此处的PowerShell字符串,powershell,escaping,herestring,Powershell,Escaping,Herestring,在脚本中放置以下内容将失败: $MyString=@' 你好 @' '@ 再见 '@ 写入主机$MyString 返回的错误如下所示: 位于C:\scripts\test.ps1:6 char:1 + '@ + ~~ 字符串缺少终止符:'。 +CategoryInfo:ParserError:(:)[],ParseException +FullyQualifiedErrorId:TerminatorExpectedAtEndOfString 在嵌套的@和@前面加上反勾号(严重重音)确实可以作

在脚本中放置以下内容将失败:

$MyString=@'
你好
@'
'@
再见
'@
写入主机$MyString
返回的错误如下所示:

位于C:\scripts\test.ps1:6 char:1
+ '@
+ ~~
字符串缺少终止符:'。
+CategoryInfo:ParserError:(:)[],ParseException
+FullyQualifiedErrorId:TerminatorExpectedAtEndOfString
在嵌套的
@
@
前面加上反勾号(严重重音)确实可以作为转义字符,但是它也被视为文字,因此会出现在
$MyString
的输出中

是否有一种正确的方法可以在不干扰输出的单引号内转义单引号内的单引号内字符串

NB:

我应该提到,外部here字符串的内容是动态填充的,内容由另一个程序作为命令行参数提供给powershell脚本。这并没有反映在示例代码中,因为我不想用我非常具体的、有点小众的实现来掩盖这个问题


外部here字符串不太可能包含内部here字符串(但可能会发生),因此我觉得有必要进行一些防御性编程以适应这种情况。

使用双引号,外部here字符串可以:

$MyString = @"
hello
@'
'@
bye
"@
$MyString = @'
hello
@"
"@
bye
'@
或对于内部字符串:

$MyString = @"
hello
@'
'@
bye
"@
$MyString = @'
hello
@"
"@
bye
'@
尝试使用ScriptBlock(用{}括起来)代替外部的Here字符串。 它适用于原始示例:

$MyString = {
hello
@'
'@
bye
}
write-host $MyString
结果:

PS > $MyString = {
>> hello
>> @'
>> '@
>> bye
>> }
>> write-host $MyString
>>

hello
@'
'@
bye

PS >
注意开头和结尾的额外空行。如果省略{和}之前的换行符,可以避免它们

如果需要,可以使用ToString()函数将ScriptBlock显式转换为字符串


不确定此解决方案是否适用于任何用例,但它看起来相当干净,因为ScriptBlock接受所有内容而不进行解释,不会被任何大括号混淆,也不会对任何引号感兴趣。

我在脚本中使用单引号,因为它可能包含HTML。如果我使用双引号,则javascript函数调用将被误解为PowerShell子表达式,并因此展开。然后对内部here字符串使用双引号。我无法控制提供的输入。外部进程调用powershell脚本,并将here字符串的内容作为参数提供。请使用问题的完整描述更新您的问题。我们不是在这里玩20个问题。请接受我的道歉-我确实可以控制外部here字符串中的内容。否则我怎么能逃脱呢??将内部here字符串更改为使用双引号,我将接受它。这似乎是用最干净的方式更新内容