批处理之家's Archiver

5i365 发表于 2022-3-30 23:24

PowerShell将多行文本中符合条件的字段提取为hash表的键值对

我想把多行文本中, [color=#ff0000]#开始  #结束[/color] 中间那几行中满足条件 [color=#ff00ff]"[/color]xxx[color=#ff00ff]", //[/color]xx 的字段,即[color=#ff00ff]粉色[/color]字部分, 提取为hash表的键值对,即[color=#0000ff]蓝色字[/color]部分
最后期待的结果像下面这样, 即:将hash表所有键的值先分别用""括起来后, 然后再连成一行,值与值之间有空格, 还有,在第一个键值后面加一对空双引号,即下面[color=#ff0000]红色引号[/color]
"在东京" [color=#ff0000]""[/color] "在纽约" "在刚果"

提取键值对的代码还没有写, 感觉要用正则匹配, 正则的规则,双引号[color=#ff00ff]""[/color]内是值[color=#ff00ff], //[/color]后是键【[color=#ff00ff],[/color]前后可能会有空格】, 估计会用到[color=#ff0000] $1[/color]和[color=#ff0000]$2[/color]的交换

将所有键的值连成一行的代码写了, 但是在第一个键值后面添加一对空引号的代码还没有写,

求路过高手指教, 提前感谢


@"
岁月难得沉默
秋风厌倦漂泊
夕阳赖着不走
挂在墙头舍不得我
昔日伊人耳边话
已和潮声向东流
再回首
[color=#ff0000]#开始[/color]
[color=#000000]      黄种人[/color][color=#ff00ff]"在东京", //日本[/color]
[color=#000000]             白人[/color][color=#ff00ff]"在纽约", //美国[/color]
[color=#ff00ff]
"在刚果",//南非[/color][color=#ff00ff]
        [/color][color=#000000]黑人//印度[/color]
[color=#000000]
[/color][color=#ff0000]#结束[/color]
往事也随枫叶一片片落
爱已走到尽头
恨也放弃承诺
命运自认幽默
想法太多由不得我
壮志凌云几分酬
知己难逢几人留
"@

#Todo 提取键值对的代码还未写

$Args = [ordered]@{[color=#0000ff]
日本 = "在东京"[/color][color=#0000ff]
美国  = "在纽约"[/color][color=#0000ff]
南非  = "在刚果"[/color]
}

$Args.Values | %{ '"' + $_ + '"' } | tee -var a | Out-Null
$a -join ' '

#期待输出的结果
"在东京" "" "在纽约" "在刚果"

for_flr 发表于 2022-3-31 09:45

[code]$pattern1="#开始(.*)#结束"
$pattern2='"(\w+)",\s?//(\w+)'
$hash=@{}
$txt=(gc a.txt) -join "|"
if($txt -match $pattern1){
    $target=$matches[1].split('|')
}
foreach($line in $target){
    if($line -match $pattern2){
        $hash[$matches[2]]=$matches[1]
    }
}
$hash
$hash.values
$null=[console]::readkey()[/code]

5i365 发表于 2022-3-31 10:15

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253538&ptid=62168]2#[/url] [i]for_flr[/i] [/b]


   感谢大侠分享, 有点难度, 我得慢慢消化

for_flr 发表于 2022-3-31 10:17

if($line -match $pattern2){$hash[$matches[2]]=$matches[1]}
就一条命令创建键值对,不算太绕吧。

其他的只是为了取#开始#结束之间的文本。
一起坐等高手。

5i365 发表于 2022-3-31 10:29

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253543&ptid=62168]4#[/url] [i]for_flr[/i] [/b]

嗯, 大侠的代码确实好理解, 前面发贴时, 先感觉花了两段匹配, 就感觉绕了, 其实这样分段取值好理解,

5i365 发表于 2022-3-31 10:37

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253543&ptid=62168]4#[/url] [i]for_flr[/i] [/b]


   加了有序hash类型, 防止参数位置变化, 现在就剩下另一个小问题了,
[code]$s = @"
岁月难得沉默
秋风厌倦漂泊
夕阳赖着不走
挂在墙头舍不得我
昔日伊人耳边话
已和潮声向东流
再回首
#开始
      黄种人"在东京", //日本
             白人"在纽约", //美国

"在刚果",//南非
        黑人//印度

#结束
往事也随枫叶一片片落
爱已走到尽头
恨也放弃承诺
命运自认幽默
想法太多由不得我
壮志凌云几分酬
知己难逢几人留
"@

$txt = $s -split '\n' -join "|"

$pattern1 = "#开始(.*)#结束"
$pattern2 = '"(\w+)",\s?//(\w+)'
$hash = [ordered]@{ }

if ($txt -match $pattern1)
{
        $target = $matches[1].split('|')
}
$target
foreach ($line in $target)
{
        if ($line -match $pattern2)
        {
                $hash[$matches[2]] = $matches[1]
        }
}
#$hash
$hash.values
#$null = [console]::readkey()[/code]

5i365 发表于 2022-3-31 10:40

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253543&ptid=62168]4#[/url] [i]for_flr[/i] [/b]


   大侠请教一个小问题, 上面我改的代码中, 下面这句, 为什么有时 \n不行, 要\r\n ? 而有时反过来才行 真是怪了[color=#c0be][font=Monaco, Consolas, "][size=12px]
[/size][/font][/color]
[font=Monaco, Consolas, "][color=#ff0000][size=12px]$txt = $s -split '\n' -join "|"[/size][/color][/font]

for_flr 发表于 2022-3-31 10:59

[code]$pattern2 = '"(\w+)",\s?//(\w+)' 改成 $pattern2 = '("\w+"),\s?//(\w+)' [/code]这样可以把双引号添进键值。[code]$abc=$hash.values.split()
$abc[0]+'""'+$abc[1..$abc.count][/code]将键值连成一行。

5i365 发表于 2022-3-31 11:06

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253554&ptid=62168]8#[/url] [i]for_flr[/i] [/b]


感谢分享帮助, 学习了

5i365 发表于 2022-3-31 11:38

[i=s] 本帖最后由 5i365 于 2022-3-31 11:41 编辑 [/i]

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253554&ptid=62168]8#[/url] [i]for_flr[/i] [/b]


   大侠好, 想请教一个问题, 下面的代码, 输出的结果是: hash表对象的属性,即[color=#0000ff]蓝色字[/color], 我想输出hash对象的定义的字符串,即[color=#ff0000]红色字, [/color][color=#000000]
[/color]
[color=#000000]我找了下相关函数没有找到, 我印象中在哪里看到过, 字符串转对象, 对象转字符串,还有一些对象, 是可以互转的[/color]
[color=#000000]
[/color][color=#0000ff]Name                           Value[/color]
[color=#0000ff]----                           -----[/color]
[color=#0000ff]日本                             "在东京"[/color]
[color=#0000ff]美国                             "在纽约"[/color]
[color=#0000ff]南非                             "在刚果"[/color]

------------------------------------------------------------------
[color=#ff0000]$hash = [ordered]@{[/color]
[color=#ff0000]
日本 = "在东京"[/color]
[color=#ff0000]
美国 = "在纽约"[/color]
[color=#ff0000]
南非 = "在刚果"[/color]
[color=#ff0000]}[/color]


[code]$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[/code]

5i365 发表于 2022-3-31 12:35

[i=s] 本帖最后由 5i365 于 2022-3-31 13:35 编辑 [/i]

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253554&ptid=62168]8#[/url] [i]for_flr[/i] [/b]


   我想了一个新的插入方法
$hash.Insert(1, "", "")
[size=12px]($hash.values | %{ '"' + $_ + '"' }) -join " "[/size]

5i365 发表于 2022-3-31 17:25

[b]回复 [url=http://www.bathome.net/redirect.php?goto=findpost&pid=253554&ptid=62168]8#[/url] [i]for_flr[/i] [/b]


   把hash表对象定义,还原回字符串, 我找到了关键的代码, 但是还差首和尾的定义, 怎么接上?
[code]$hash.GetEnumerator() | %{
        $_.key + "=" + $_.Value
}[/code]

页: [1]

Powered by Discuz! Archiver 7.2  © 2001-2009 Comsenz Inc.