PowerShell - 将 属性 名称从 Pascal 大小写转换为带下划线的大写
PowerShell - Convert Property Names from Pascal Case to Upper Case With Underscores
假设我有一个这样的对象:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
我想结束:
$test = @{
THIS_IS_THE_FIRST_COLUMN = "ValueInFirstColumn";
THIS_IS_THE_SECOND_COLUMN = "ValueInSecondColumn"
}
无需手动对新列名称进行编码。
这显示了我想要的值:
$test.PsObject.Properties | where-object { $_.Name -eq "Keys" } | select -expand value | foreach{ ($_.substring(0,1).toupper() + $_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()} | Out-Host
这导致:
THIS_IS_THE_FIRST_COLUMN
THIS_IS_THE_SECOND_COLUMN
但现在我似乎无法弄清楚如何将这些新值分配回对象。
这似乎有效。不过,我最终把东西放在了一个新的哈希表中。
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
$test2=@{}
$test.PsObject.Properties |
where-object { $_.Name -eq "Keys" } |
select -expand value | foreach{ $originalPropertyName=$_
$prop=($_.substring(0,1).toupper() + $_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$test2.Add($prop,$test[$originalPropertyName])
}
$test2
您可以按如下方式就地修改哈希表$test
:
foreach($key in @($test.Keys)) { # !! @(...) is required - see below.
$value = $test[$key] # save value
$test.Remove($key) # remove old entry
# Recreate the entry with the transformed name.
$test[($key -creplace '(?<!^)\p{Lu}', '_$&').ToUpper()] = $value
}
@($test.Keys)
从现有哈希表键创建一个数组; @(...)
确保将密钥集合复制到 静态数组 ,因为直接在修改相同哈希表的循环中使用 .Keys
属性 会休息。
循环体保存输入键的值,然后删除其旧名称下的条目。[1]
然后使用所需的名称转换在其新键名下重新创建该条目:
$key -creplace '(?<!^)\p{Lu}
匹配给定键中的每个大写字母 (\p{Lu}
),字符串开头除外 ((?<!^)
),并将其替换为 _
后跟该字母 (_$&
);将结果转换为大写 (.ToUpper()
) 生成所需的名称。
[1] 在 之前删除旧条目 添加重命名的条目可以避免 单字 名称的问题,例如作为 Simplest
,其转换后的名称 SIMPLEST
被认为是 相同的 名称,因为 PowerShell 中的哈希表不区分大小写。因此,在条目 Simplest
仍然存在时为条目 SIMPLEST
赋值实际上是针对 existing 条目,随后的 $test.Remove($key)
将简单地删除该条目条目,无需添加新条目。
指出问题的JosefZ点赞
($test.PsObject.Properties|Where-Object {$_.Name -eq "Keys"}).IsSettable
表示 False
。因此,您需要分两步完成:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
$auxarr = $test.PsObject.Properties |
Where-Object { $_.Name -eq "Keys" } |
select -ExpandProperty value
$auxarr | ForEach-Object {
$aux = ($_.substring(0,1).toupper() +
$_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$test.ADD( $aux, $test.$_)
$test.Remove( $_)
}
$test
两步法是必要的,因为尝试在唯一的管道中执行 REMOVE
和 ADD
方法会导致以下错误:
select : Collection was modified; enumeration operation may not execute.
编辑。不幸的是,上述解决方案在单字 Pascal Case 键的情况下会失败,例如Simplest = "ValueInSimplest"
。这是改进后的脚本:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
Simplest = "ValueInSimplest" # the simplest (one word) PascalCase
}
$auxarr = $test.PsObject.Properties |
Where-Object { $_.Name -eq "Keys" } |
select -ExpandProperty value
$auxarr | ForEach-Object {
$aux = ($_.substring(0,1).toupper() +
$_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$newvalue = $test.$_
$test.Remove( $_)
$test.Add( $aux, $newvalue)
}
$test
假设我有一个这样的对象:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
我想结束:
$test = @{
THIS_IS_THE_FIRST_COLUMN = "ValueInFirstColumn";
THIS_IS_THE_SECOND_COLUMN = "ValueInSecondColumn"
}
无需手动对新列名称进行编码。
这显示了我想要的值:
$test.PsObject.Properties | where-object { $_.Name -eq "Keys" } | select -expand value | foreach{ ($_.substring(0,1).toupper() + $_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()} | Out-Host
这导致:
THIS_IS_THE_FIRST_COLUMN
THIS_IS_THE_SECOND_COLUMN
但现在我似乎无法弄清楚如何将这些新值分配回对象。
这似乎有效。不过,我最终把东西放在了一个新的哈希表中。
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
$test2=@{}
$test.PsObject.Properties |
where-object { $_.Name -eq "Keys" } |
select -expand value | foreach{ $originalPropertyName=$_
$prop=($_.substring(0,1).toupper() + $_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$test2.Add($prop,$test[$originalPropertyName])
}
$test2
您可以按如下方式就地修改哈希表$test
:
foreach($key in @($test.Keys)) { # !! @(...) is required - see below.
$value = $test[$key] # save value
$test.Remove($key) # remove old entry
# Recreate the entry with the transformed name.
$test[($key -creplace '(?<!^)\p{Lu}', '_$&').ToUpper()] = $value
}
@($test.Keys)
从现有哈希表键创建一个数组; @(...)
确保将密钥集合复制到 静态数组 ,因为直接在修改相同哈希表的循环中使用 .Keys
属性 会休息。
循环体保存输入键的值,然后删除其旧名称下的条目。[1]
然后使用所需的名称转换在其新键名下重新创建该条目:
$key -creplace '(?<!^)\p{Lu}
匹配给定键中的每个大写字母 (\p{Lu}
),字符串开头除外 ((?<!^)
),并将其替换为 _
后跟该字母 (_$&
);将结果转换为大写 (.ToUpper()
) 生成所需的名称。
[1] 在 之前删除旧条目 添加重命名的条目可以避免 单字 名称的问题,例如作为 Simplest
,其转换后的名称 SIMPLEST
被认为是 相同的 名称,因为 PowerShell 中的哈希表不区分大小写。因此,在条目 Simplest
仍然存在时为条目 SIMPLEST
赋值实际上是针对 existing 条目,随后的 $test.Remove($key)
将简单地删除该条目条目,无需添加新条目。
指出问题的JosefZ点赞
($test.PsObject.Properties|Where-Object {$_.Name -eq "Keys"}).IsSettable
表示 False
。因此,您需要分两步完成:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
}
$auxarr = $test.PsObject.Properties |
Where-Object { $_.Name -eq "Keys" } |
select -ExpandProperty value
$auxarr | ForEach-Object {
$aux = ($_.substring(0,1).toupper() +
$_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$test.ADD( $aux, $test.$_)
$test.Remove( $_)
}
$test
两步法是必要的,因为尝试在唯一的管道中执行 REMOVE
和 ADD
方法会导致以下错误:
select : Collection was modified; enumeration operation may not execute.
编辑。不幸的是,上述解决方案在单字 Pascal Case 键的情况下会失败,例如Simplest = "ValueInSimplest"
。这是改进后的脚本:
$test = @{
ThisIsTheFirstColumn = "ValueInFirstColumn";
ThisIsTheSecondColumn = "ValueInSecondColumn"
Simplest = "ValueInSimplest" # the simplest (one word) PascalCase
}
$auxarr = $test.PsObject.Properties |
Where-Object { $_.Name -eq "Keys" } |
select -ExpandProperty value
$auxarr | ForEach-Object {
$aux = ($_.substring(0,1).toupper() +
$_.substring(1) -creplace '[^\p{Ll}\s]', '_$&').Trim("_").ToUpper()
$newvalue = $test.$_
$test.Remove( $_)
$test.Add( $aux, $newvalue)
}
$test