76

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

我有这个字符串...

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

我必须提取...

Hello World

最好的方法是什么?

4

8 回答 8

65

操作员测试一个正-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

于 2010-08-19T09:08:26.520 回答
50

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'
于 2010-06-09T14:02:52.903 回答
22

不确定这是否有效,但可以使用数组索引语法引用 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
于 2017-06-21T00:55:37.143 回答
13
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 作为第二个参数

于 2017-02-27T10:47:21.703 回答
7

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

$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))
于 2012-05-04T18:42:17.397 回答
5

其他解决方案

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

$text | ConvertFrom-String -TemplateContent $template
于 2017-01-29T11:05:54.887 回答
0

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

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

$result = $matches[0]
$result
Hello World
于 2014-05-29T16:06:31.340 回答
0

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

干杯..!

于 2018-08-20T07:47:51.193 回答