【问题标题】:Powershell - print only text between quotes?Powershell - 仅打印引号之间的文本?
【发布时间】:2013-01-28 18:00:05
【问题描述】:

如何让以下文本的输出只显示引号中的文本(不带引号)?

示例文本“

this is an "apple". it is red
this is an "orange". it is orange
this is an "blood orange". it is reddish

变成:

apple
orange
blood orange

如果可能的话,理想情况下我想在一个班轮中完成。我认为这是带有 -match 的正则表达式,但我不确定。

【问题讨论】:

    标签: powershell


    【解决方案1】:

    这是一种方法

    $text='this is an "apple". it is red
    this is an "orange". it is orange
    this is an "blood orange". it is reddish'
    
    $text.split("`n")|%{
    $_.split('"')[1]
    }
    

    这是成功的解决方案

    $text='this is an "apple". it is red
    this is an "orange". it is orange
    this is an "blood orange". it is reddish'
    
    $text|%{$_.split('"')[1]}
    

    【讨论】:

    • 我试过这个,但我收到一个错误:on $text.split ("`n") |%{ (doesn't contains a method named 'split')
    • 抱歉,它确实有效。但是,解决方案略有不同,因为 $text 有两个撇号(一个在开头,一个在结尾)。在我的文本示例中,没有撇号。没有他们有可能吗?
    • @MikeJ 但是你如何得到你的文本?你使用 get-content 吗?
    • 在这种情况下是 $text = appcmd list apppool
    • 尝试直接拆分 $text : $text|%{$_.split('"')[1]}
    【解决方案2】:

    使用正则表达式的另一种方式:

    appcmd list apppool | % { [regex]::match( $_ , '(?<=")(.+)(?=")' ) } | select -expa value
    

     appcmd list apppool | % { ([regex]::match( $_ , '(?<=")(.+)(?=")' )).value }
    

    【讨论】:

    • 感谢正则表达式,我喜欢它。但是你不觉得Split功能更干净吗?在这一点上的语义,因为它们都可以工作,但我更喜欢更清洁的解决方案。
    • 这取决于一个人如何知道正则表达式的语法......无论如何我发布了我的答案,因为你提到了正则表达式...... Spli 这是一个很好的解决方案!
    【解决方案3】:

    基于.NET方法[regex]::Matches()的简洁解决方案,使用PSv3+语法:

    $str = @'
    this is an "apple". it is red
    this is an "orange". it is orange
    this is an "blood orange". it is reddish
    '@
    
    [regex]::Matches($str, '".*?"').Value -replace '"'
    

    正则表达式 ".*?" 匹配 "..."-enclosed 标记,.Matches() 返回所有标记; .Value 提取它们,-replace '"' 去除 " 字符。

    这意味着上述内容甚至可以使用 multiple "..." 每行标记(但请注意,使用 embedded escaped " 字符提取标记。(例如,@ 987654333@) 不起作用)。


    使用-match 运算符 - 仅查找 a(一个)匹配 - 是一个选项仅当

    • 您将输入分成
    • 并且每一行包含最多 1 个 "..." 令牌(对于问题中的示例输入来说是正确的)。

    这是一个 PSv4+ 解决方案:

    # Split string into lines, then use -match to find the first "..." token
    ($str -split "`r?`n").ForEach({ if ($_ -match '"(.*?)"') { $Matches[1] } })  
    

    自动变量$Matches 包含先前-match 操作的结果(如果LHS 是一个标量)并且索引[1] 包含第一个(也是唯一一个)捕获组(@ 987654340@) 匹配。


    如果-match 有一个名为-matchall 的变体会很方便,这样人们就可以这样写:

    # WISHFUL THINKING (as of PowerShell Core 6.2)
    $str -matchall '".*?"' -replace '"'
    

    请参阅 GitHub 上的 this feature suggestion

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-10-04
      • 1970-01-01
      • 2023-03-25
      • 2013-11-16
      • 2018-01-11
      相关资源
      最近更新 更多