【问题标题】:Extract a substring using PowerShell使用 PowerShell 提取子字符串
【发布时间】:2011-02-28 15:41:36
【问题描述】:

如何使用 PowerShell 提取子字符串?

我有这个字符串...

"-----start-------Hello World------end-------"

我必须提取...

Hello World

最好的方法是什么?

【问题讨论】:

  • 相反,我想要所有东西,但 Hello World,这很好用 --> $str -replace '\w\w\w\w\w.\w\w\w\w\w'

标签: string powershell powershell-2.0


【解决方案1】:

-match 运算符测试一个正则表达式,将它与魔术变量 $matches 结合以获得您的结果

PS C:\> $x = "----start----Hello World----end----"
PS C:\> $x -match "----start----(?<content>.*)----end----"
True
PS C:\> $matches['content']
Hello World

如果对正则表达式有疑问,请查看此网站:http://www.regular-expressions.info

【讨论】:

  • 我不知道在 powershell 中做正则表达式这么简单!非常感谢!!!
  • 当我尝试这个时,我看不到“真”,但是当我在一个多行变量(输出 ping)上尝试这个时,我看到了完整的行。因此,执行一次 ping 并保存回复,然后我只想搜索“Reply from 149.155.224.1: bytes=32 time
  • 嗨DevilWAH,我建议开始一个新问题以提供上下文。我的猜测是您可能看到了与将数组发送到 -match 运算符相关的内容?没有上下文很难说。祝你好运。
  • 如果有多个匹配项怎么办?
【解决方案2】:

Substring 方法为我们提供了一种根据起始位置和长度从原始字符串中提取特定字符串的方法。如果仅提供一个参数,则将其作为起始位置,并输出字符串的其余部分。

PS > "test_string".Substring(0,4)
Test
PS > "test_string".Substring(4)
_stringPS >

但这更容易......

 $s = 'Hello World is in here Hello World!'
 $p = 'Hello World'
 $s -match $p

最后,通过仅选择 .txt 文件并搜索出现“Hello World”的目录进行递归:

dir -rec -filter *.txt | Select-String 'Hello World'

【讨论】:

  • +1:但是,捕获开始和结束标签之间的内容的正则表达式会更好,例如“-----start-------(.+?)-----end------”(未经测试的正则表达式,我不是正则表达式大师)
【解决方案3】:

不确定这是否有效,但 PowerShell 中的字符串可以使用数组索引语法引用,类似于 Python。

这并不完全直观,因为index = 0 引用了第一个字母,但确实如此:

  • 允许第二个索引号比字符串长,而不会产生错误
  • 反向提取子字符串
  • 从字符串末尾提取子字符串

这里有一些例子:

PS > 'Hello World'[0..2]

产生结果(为清楚起见包括索引值 - 未在输出中生成):

H [0]
e [1]
l [2]

通过-join '' 可以使其更有用:

PS > 'Hello World'[0..2] -join ''
Hel

使用不同的索引可以获得一些有趣的效果:

转发

使用小于第二个的第一个索引值,子字符串将按照您的预期向前提取。这次第二个索引值远超字符串长度但没有报错:

PS > 'Hello World'[3..300] -join ''
lo World

不同于:

PS > 'Hello World'.Substring(3,300)
Exception calling "Substring" with "2" argument(s): "Index and length must refer to a location within
the string.

向后

如果您提供的第二个索引值低于第一个索引值,则该字符串将反向返回:

PS > 'Hello World'[4..0] -join ''
olleH

从头到尾

如果你使用负数,你可以从字符串的末尾引用一个位置。要提取'World',最后5个字母,我们使用:

PS > 'Hello World'[-5..-1] -join ''
World

【讨论】:

  • 你也可以使用-join的一元形式:-join 'Hello World'[-5..-1]
【解决方案4】:
PS> $a = "-----start-------Hello World------end-------"
PS> $a.substring(17, 11)
         or
PS> $a.Substring($a.IndexOf('H'), 11)

$a.Substring(argument1, argument2) --> 这里argument1 = 所需字母的起始位置,argument2 = 你想要作为输出的子字符串的长度。

这里 17 是字母表的索引 'H',由于我们要打印到 Hello World,我们提供 11 作为第二个参数

【讨论】:

    【解决方案5】:

    基于马特的回答,这是一个跨换行符搜索并且易于修改以供您自己使用的答案

    $String="----start----`nHello World`n----end----"
    $SearchStart="----start----`n" #Will not be included in results
    $SearchEnd="`n----end----" #Will not be included in results
    $String -match "(?s)$SearchStart(?<content>.*)$SearchEnd"
    $result=$matches['content']
    $result
    

    --

    注意:如果您想对文件运行此操作,请记住 Get-Content 返回一个数组而不是单个字符串。您可以通过执行以下操作来解决此问题:

    $String=[string]::join("`n", (Get-Content $Filename))
    

    【讨论】:

      【解决方案6】:

      其他解决方案

      $template="-----start-------{Value:This is a test 123}------end-------"
      $text="-----start-------Hello World------end-------"
      
      $text | ConvertFrom-String -TemplateContent $template
      

      【讨论】:

      • 大吃一惊。 PowerShell有这么疯狂的功能
      【解决方案7】:

      由于字符串并不复杂,所以不需要添加RegEx字符串。一个简单的匹配就可以了

      $line = "----start----Hello World----end----"
      $line -match "Hello World"
      $matches[0]
      Hello World
      
      $result = $matches[0]
      $result
      Hello World
      

      【讨论】:

      • 提取已知字符串是没有意义的,因为您已经知道该字符串。
      • 这不是没有意义的。如果您要根据子字符串是否存在进行一些处理,则使用它很方便,因为它可以归结为真/假,这是决策结构需要进行的。
      【解决方案8】:

      我需要在日志文件中提取几行,这篇文章有助于解决我的问题,所以我想在这里添加它。如果有人需要提取多行,您可以使用脚本获取与该字符串匹配的单词的索引(我正在搜索“Root”)并提取所有行中的内容。

      $File_content = Get-Content "Path of the text file"
      $result = @()
      
      foreach ($val in $File_content){
          $Index_No = $val.IndexOf("Root")
          $result += $val.substring($Index_No)
      }
      
      $result | Select-Object -Unique
      

      干杯..!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-06-25
        • 1970-01-01
        • 1970-01-01
        • 2013-04-09
        • 1970-01-01
        • 1970-01-01
        • 2017-04-01
        相关资源
        最近更新 更多