powershell - 未引用的关键规则和最佳实践
问题描述
这个问题与:
涉及变量引用和子表达式的参数模式中未引用的标记:为什么它们有时会分成多个参数?.
当我的项目可能请求时,我得到了这个Remove quotes in HashTables Keys 。ConvertTo-Expression
关键是我并不完全清楚何时应该在哈希表中实际引用键。
与参数值一样,不带引号的哈希表键的使用仅限于某些字符。
不允许使用多个字符(包括空格),例如:
$Options = @{
Margin = 2
Padding = 2
Font-Size = 24
}
会导致错误:
Line | 4 | Font-Size = 24 | ~ | Missing '=' operator after key in hash literal.
在某些情况下,只是字符的顺序可能会导致错误甚至陷阱,例如:
$Hashtable = @{
U2 = 'YouTo'
2U = 'ToYou'
}
$Hashtable.keys
2
U2
(这是因为U2
键将被解释为一种类型,[UInt32]
这意味着$HashTable.2U
将正确显示值 but$HashTable.2
和not。)$HashTable.'2'
$HashTable.'2U'
除了我正在寻找一些记录在案的最佳实践的问题之外,我想安全地测试是否需要引用字符串,例如:
IsStringConstant 'Margin' # True
IsStringConstant 'Font-Size' # False
IsStringConstant 'U2' # True
IsStringConstant '2U' # False
我一直在玩AST,但这需要我先构建一个ScriptBlock
,这被认为是不安全的。
有没有办法检查字符串是否需要为哈希表键引用?
解决方案
我一直在玩 AST,但这需要我先构建一个
ScriptBlock
,这被认为是不安全的。
[scriptblock]
这(幸运的是)不正确 - 您可以从源代码生成 AST,而无需通过调用编译封闭Parser.ParseInput()
:
$tokens = @()
$errors = @()
$AST = [System.Management.Automation.Language.Parser]::ParseInput('U2',[ref]$tokens,[ref]$null)
在这种情况下,您实际上不需要检查 AST,您可以根据解析虚拟哈希表文字产生的令牌确定哈希表成员键是否有效:
function Test-IsValidHashtableStringLiteral
{
param([string]$Identifier)
$dummyTable = '@{{{0}=$()}}' -f $Identifier
$tokens = @()
$errors = @()
$null = [System.Management.Automation.Language.Parser]::ParseInput($dummyTable, [ref]$tokens, [ref]$errors)
if($errors.Count){
# Parsing our dummy table resulted in errors, no good
# This would be the case for `Font-Size`
return $false
}
# No errors, let's ensure the member name is recognized
# as an identifier and not a value literal (like 2u in PowerShell >6)
$memberName = $tokens[1]
return $memberName.Kind -eq 'Identifier'
}
请注意:结果是特定于版本的- 换句话说,如果您使用上述技术并在 PowerShell 5.1 上运行ConvertTo-Expression
您的2u
示例,则生成的表达式只能在 5.1 中正常工作 - 以生成您需要的 7.0 兼容表达式在 7.0 上运行它。
好消息是解析器接口自 PowerShell 3.0 以来一直保持稳定,并且语言基础结构非常向后兼容,因此这种方法适用于从 3.0 到 7.x 的所有版本
推荐阅读
- c++ - 在 OSX Big Sur 上使用 OpenGL 4.x 进行开发
- http - 使用 Apps 脚本的 Google Calendar API 批量插入事件
- java - Selenium:无法与字段集标记中的元素交互
- reactjs - 如何使用 gatsby 将特定 url 重定向到主页而不是重定向到 404?
- javascript - Ajax CORS 问题:如果我使用 no-cors,授权标头会消失
- node.js - req.body 未定义 - React & Nodejs
- symfony4 - 如何使用 Rest API 获取 Shopware 6 中产品的媒体文件?
- android-studio - 断言失败'url!= null':不是真的错误
- java - Android Studio 为什么 CardView 不起作用?
- html - 将回复电子邮件格式化为 HTML