【问题标题】:Extract string between another string and a character (PowerShell)在另一个字符串和一个字符之间提取字符串(PowerShell)
【发布时间】:2021-08-03 00:10:35
【问题描述】:

我是第一次使用 PowerShell 进行编程,但对它不是很熟悉。 我有一个包含许多行的文件,例如“标签 ABCDEFGH 的 AddItems 失败,类型 VT_R4:ItemID 不在服务器地址空间 (c0040007) 中”。 我只想检索 ABCDEFGH 字符串。我首先尝试了.Substring() 方法,但它并没有真正起作用,因为我试图检索的所有字符串的长度都不相同。这个想法基本上是取出“tag”和“,”之间包含的每个字符串,但我不知道如何编码。

$log = get-content C:\Logs\mylog.txt
foreach ($line in $log) { 
    if ($line -like "*tag*") {
        $line.substring(24,36)
        $line | out-file -FilePath "C:\Logs\ItemIDs.txt" -Append
    }
}

下面是一个输入示例:

tag Z..ANTW@ENERGY@C605_RAIL4_MC_403
tag ANTW@CALI@CALLISTO@130LI513B.PV,

Z..ANTW@ENERGY@C605_RAIL4_MC_403ANTW@CALI@CALLISTO@130LI513B.PV都是ABCDEFGH,而且第一个例子少了几个字母。

非常感谢您的帮助,我们将不胜感激!

【问题讨论】:

  • 如果你的 abcdef 是通用的,你必须在之前和之后显示标签..

标签: string powershell substring character extract


【解决方案1】:

我确信我们可以找到简单的字符串方法(如 .SubString().IndexOf())的排列和组合来做到这一点,但这样做总是需要输入字符串具有可靠程度的一致性。也就是说,使用您提供的示例:

$String = "AddItems failed for tag ABCDEFGH, type VT_R4: The ItemID is not in the server address space (c0040007)"

$OutputString = $String.SubString($String.IndexOf("tag")+4)
$OutputString = ($OutputString -split ',')[0]

这假定单词“tag”总是在“ABCDEFGH”之前,而“,”总是在它后面。并说找到标签的起始位置添加4。然后使用-split 得到一个数组,但只给我第一个元素,它应该是“,”左边的任何东西。

然而,与Mathias's characteristically good answer 相似,我认为RegEx 更适合这个(不是双关语)。但是,我喜欢为此使用环视:

我不知道这是否完美,也许可以提炼。我不认为自己是 RegEx 专家...

$String = "AddItems failed for tag ABCDEFGH, type VT_R4: The ItemID is not in the server address space (c0040007)"
$String -match "(?!tag)\w*(?=,)"

这应该返回:ABCDEFGH

简而言之,这意味着返回在“tag”和“,”之间找到的文本。

将其与您的原始代码一起使用:

$log     = Get-Content 'C:\Logs\mylog.txt'
$pattern = '(?<=tag\s{1}).*(?=\,)'

ForEach ($line in $log) { 
    if ( $line -match $pattern ) {
        $Matches[0] | Out-File -FilePath "C:\Logs\ItemIDs.txt" -Append
    }
}

【讨论】:

    【解决方案2】:

    使用-match 正则表达式运算符测试给定字符串是否包含特定模式,然后使用$Matches 自动变量提取捕获的任何组:

    if('tag ANTW@CALI@CALLISTO@130LI513B.PV,' -match 'tag ([^,]+),'){
        $Matches[1] 
    }
    

    你会发现上面语句的输出是字符串ANTW@CALI@CALLISTO@130LI513B.PV,所以假设这就是你所需要的,只需输出将它添加到你的循环并将$Matches[1]输出到文件:

    foreach($line in $log){
        if($line -match 'tag ([^,]+),'){
            $Matches[1] |Out-File -FilePath C:\Logs\ItemIDs.txt -Append
        }
    }
    

    【讨论】:

    • 我不知道正则表达式,但你的方法效果很好!非常感谢
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-03-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 2017-12-24
    相关资源
    最近更新 更多