标题: [问题求助] PowerShell把hash表定义还原回字面字符串 [打印本页]
作者: 5i365 时间: 2022-3-31 17:35 标题: PowerShell把hash表定义还原回字面字符串
此贴由 另一贴引出 http://www.bathome.net/thread-62168-1-1.html
下面的代码, 输出的结果是: hash表对象的属性,即蓝色字, 我想输出hash对象的定义的字符串,即红色字,
我找到了【hash表对象定义还原回字符串】的下面关键代码, 有两种,效果相同, 但是还差首和尾的定义, 怎么接上? 【三行代码的结果也有瑕疵,值没有被双引号引起来】
$hash.GetEnumerator() | %{
$_.key + "=" + $_.Value
}
----------------------------------上面是用枚举器的方法,下面是用遍历键值的方法
foreach ($key in $hash.keys) {
$key + "=" + $hash[$key]
}
感觉从正则匹配的地方生成可能更简单,
或可能还有更好的思路和方法, 请求路过高手支招, 提前感谢!
-----------------------------------------------------------------------------------------------------------------------------
Name Value
---- -----
日本 "在东京"
美国 "在纽约"
南非 "在刚果"
------------------------------------------------------------------
$hash = [ordered]@{
日本 = "在东京"
美国 = "在纽约"
南非 = "在刚果"
}- $s = @"
- 岁月难得沉默
- 秋风厌倦漂泊
- 夕阳赖着不走
- 挂在墙头舍不得我
- 昔日伊人耳边话
- 已和潮声向东流
- 再回首
- #开始
- 黄种人"在东京", //日本
- 白人"在纽约", //美国
-
- "在刚果",//南非
- 黑人//印度
-
- #结束
- 往事也随枫叶一片片落
- 爱已走到尽头
- 恨也放弃承诺
- 命运自认幽默
- 想法太多由不得我
- 壮志凌云几分酬
- 知己难逢几人留
- "@
-
- $txt = $s -split '\n' -join "|"
-
- $pattern1 = "#开始(.*)#结束"
- $pattern2 = '("\w+"),\s?//(\w+)'
- $hash = [ordered]@{ }
-
- if ($txt -match $pattern1)
- {
- $target = $matches[1].split('|')
- }
-
- foreach ($line in $target)
- {
- if ($line -match $pattern2)
- {
- $hash[$matches[2]] = $matches[1]
- }
- }
- $hash
复制代码
作者: went 时间: 2022-3-31 20:12
用-f格式化就很好操作- $s = @'
- 岁月难得沉默
- 秋风厌倦漂泊
- 夕阳赖着不走
- 挂在墙头舍不得我
- 昔日伊人耳边话
- 已和潮声向东流
- 再回首
- #开始
- 黄种人"在东京", //日本
- 白人"在纽约", //美国
-
- "在刚果",//南非
- 黑人//印度
-
- #结束
- 往事也随枫叶一片片落
- 爱已走到尽头
- "在刚f果",//南非
- 恨也放弃承诺
- 命运自认幽默
- 想法太多由不得我
- 壮志凌云几分酬
- 知己难逢几人留
- '@
-
- $hash = [ordered]@{}
- if($s -match '(?s)#开始(.*?)#结束'){
- [regex]::Matches($Matches[1],'(?m)"(.+?)",\s*//(.+?)$') | foreach { $hash.($_.Groups[2].Value) = $_.Groups[1].Value }
- }
-
- $hash.Keys | foreach { '{0} = "{1}"' -f $_,$hash[$_] }
复制代码
作者: 5i365 时间: 2022-3-31 21:23
本帖最后由 5i365 于 2022-3-31 21:24 编辑
回复 2# went
大侠牛X, 确实好理解多了, 怎样生成下面格式的字面值? 我是想生成下面的字面值, 然后存到变量$h中, 后面想显示的时候, 直接放出$h变量
$hash = [ordered]@{
日本 = "在东京"
美国 = "在纽约"
南非 = "在刚果"
}
作者: 5i365 时间: 2022-3-31 21:36
本帖最后由 5i365 于 2022-3-31 21:53 编辑
回复 2# went
我自己改成下面这样, 会多一个空行, 另外感觉太绕
- $hash.Keys | foreach { '{0} = "{1}"' -f $_, $hash[$_] } | Out-String | tee -var mid | Out-Null
- $start = '$hash = [ordered]@{'
- $end = '}'
-
- $h = @"
- $start
- $mid
- $end
- "@
-
- $h
复制代码
作者: went 时间: 2022-3-31 21:54
&{
代码块
}
可以把整个代码块的输出转换为一个字符串- $hash = [ordered]@{}
- if($s -match '(?s)#开始(.*?)#结束'){
- [regex]::Matches($Matches[1],'(?m)"(.+?)",\s*//(.+?)$') | foreach { $hash.($_.Groups[2].Value) = $_.Groups[1].Value }
- }
-
- $h =
- &{
- '$hash = [ordered]@{'
- $hash.Keys | foreach { '{0}{1} = "{2}"' -f "`t",$_,$hash[$_] }
- '}'
- }
-
- $h
复制代码
作者: 5i365 时间: 2022-3-31 21:57
回复 5# went
大侠实在太牛X了, 精干高效,炉火纯青!!
作者: went 时间: 2022-3-31 22:01
本帖最后由 went 于 2022-3-31 22:05 编辑
纠正一下
&{
代码块
} 转换为Object数组
&{
代码块
} | Out-String 转换为字符串
作者: 5i365 时间: 2022-4-1 07:21
本帖最后由 5i365 于 2022-4-1 07:24 编辑
回复 7# went
感谢大侠提醒, gettype看了一下, 确实如此, 另外大侠能解惑一下您正则中的符号的含义吗?
for_flr 大侠写的正则如下, 我能理解,
$pattern1 = "#开始(.*)#结束"
$pattern2 = '("\w+"),\s?//(\w+)'
--------------------------------------------------
您写的正则如下
'(?s)#开始(.*?)#结束'
'(?m)"(.+?)",\s*//(.+?)$'
--------------------------------------------------
量词+或*后加了? 应该是匹配尽可能的少
但是正则前都多了括号(?s)和(?m)
(?m)我好像在哪里看到过, 说的是匹配多行, 但是(?s)这个参数没找到相关资料, ps官方的MSDN也没找到,
大侠能解释一下它的含义吗? 能引用一个资料出处就好了, 再次感谢.
放上官方PS的正则链接供大家参考
https://docs.microsoft.com/zh-cn/powershell/module/microsoft.powershell.core/about/about_regular_expressions?view=powershell-7.2
作者: went 时间: 2022-4-1 11:32
这里面有关于单行和多行匹配的详细介绍
https://docs.microsoft.com/zh-cn ... -expression-options
作者: 5i365 时间: 2022-4-1 16:38
本帖最后由 5i365 于 2022-4-1 19:21 编辑
回复 9# went
非常感谢大侠的指引!!!原来是单行模式, 这样就不用 像 for_flr 大侠代码那样, 先用 | 拼接了, 方便了很多
刚又入了一个坑, 我把要处理的文本外置存为了s.txt, 再次执行后, =号后面换行了, 结果如下!
$hash = [ordered]@{
日本
= "在东京"
美国
= "在纽约"
南非
= "在刚果"
}
- $s = gc s.txt -enc UTF8 -raw
-
- $hash = [ordered]@{ }
- if ($s -match '(?s)#开始(.*?)#结束')
- {
- [regex]::Matches($Matches[1], '(?m)"(.+?)",\s*//(.+?)$') |
- foreach { $hash.($_.Groups[2].Value) = $_.Groups[1].Value }
- }
-
-
- $h = &{
- '$hash = [ordered]@{'
- $hash.Keys | foreach { '{0}{1} = "{2}"' -f "`t", $_, $hash[$_] }
- '}'
- }
-
- $h
复制代码
作者: went 时间: 2022-4-1 19:32
回复 10# 5i365
我运行没问题
作者: 5i365 时间: 2022-4-1 20:49
本帖最后由 5i365 于 2022-4-1 20:51 编辑
回复 11# went
我在powershell studio 里, 显示换行了, 但是我在powershell ISE里, 显示是好的, 但是定向后, 也换行了,
$h > "C:\Users\Administrator\Desktop\aaa.txt"
s.txt 下载 https://send.cm/d/9oH1
- $s = gc "C:\Users\Administrator\Desktop\s.txt" -enc UTF8 -raw
- $s -match '(?s)#开始(.*?)#结束'
- $matches[0]
-
- $hash = [ordered]@{ }
- if ($s -match '(?s)#开始(.*?)#结束')
- {
- [regex]::Matches($Matches[1], '(?m)"(.+?)",\s*//(.+?)$') |
- foreach { $hash.($_.Groups[2].Value) = $_.Groups[1].Value }
- }
-
-
- $h = &{
- '$hash = [ordered]@{'
- $hash.Keys | foreach { '{0}{1} = "{2}"' -f "`t", $_, $hash[$_] }
- '}'
- }
-
- $h>"C:\Users\Administrator\Desktop\aaa.txt"
复制代码
作者: went 时间: 2022-4-1 21:14
本帖最后由 went 于 2022-4-1 21:16 编辑
正则改一下,把末尾的换行符去掉- '(?m)"(.+?)",\s*//(\S+?)\s$'
复制代码
- '(?m)"(.+?)",\s*//\s*(.+?)\s*$'
复制代码
作者: 5i365 时间: 2022-4-1 21:20
回复 13# went
大侠牛X, 显示和输出都没换行了.
正则真是字符串处理的万金油啊,!!!
欢迎光临 批处理之家 (http://www.bathome.net/) |
Powered by Discuz! 7.2 |