且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

使用 PowerShell 将字符串解析为对象时遇到问题

更新时间:2023-11-14 17:20:46

如果:

  • 您可以依赖从不包含 : 自身的值
  • 您不介意生成的自定义对象的属性不反映输入顺序(尽管您可以通过管道传递到 Select-Object 调用枚举轻松但效率低下)属性),
  • you can rely on values never containing : themselves
  • you don't mind that the properties of the resulting custom objects don't reflect the input order (though you could easily, but inefficiently, correct that with piping to a Select-Object call enumerating the properties explicitly),

您可以使用 ConvertFrom-StringData(我建议避免使用挑剔且文档不足的 ConvertFrom-String):

$string.Trim() -split '(?m)(?=^City\b)' -ne '' | ForEach-Object { 
  [pscustomobject] ($_ -replace ':', '=' | ConvertFrom-StringData)
}  # | Export-Csv ....

注意:转换到 [pscustomobject] 需要 PSv3+;在 PSv2 上,使用 New-Object PSCustomObject -Property (...)

Note: Casting to [pscustomobject] requires PSv3+; on PSv2, use New-Object PSCustomObject -Property (...)

  • $string.Trim() -split '(?m)(?=^City\b)' -ne '' 将输入行分割成行块每个代表一个对象;拆分由以City开头的行执行;-ne '' 过滤掉解析输入开头的空块.

  • $string.Trim() -split '(?m)(?=^City\b)' -ne '' splits the input lines into blocks of lines each representing one object; splitting is performed by lines that start with City; -ne '' filters out the empty block that results from parsing the start of the input.

  • .Trim() 需要忽略字符串开头的空行.
  • .Trim() is needed to ignore empty lines at the start of the string.

$_ -replace ':', '=' |ConvertFrom-StringData 将每个块转换为
= 行,ConvertFrom-StringData 作为一个组转换为一个 [hashtable] 实例;因为哈希表本质上以没有保证的顺序枚举它们的条目,这是属性的输入顺序丢失的地方.

$_ -replace ':', '=' | ConvertFrom-StringData converts each block into
<key>=<value> lines that ConvertFrom-StringData converts as a group to a [hashtable] instance; because hash tables inherently enumerate their entries in no guaranteed order, this is where the input ordering of properties is lost.

Cast [pscustomobject] 将每个hashtable转换成自定义对象,隐式输出;输出可以通过管道传输到 Export-Csv.

Cast [pscustomobject] converts each hashtable to a custom object, which is implicitly output; the output can be piped to Export-Csv.