【问题标题】:Get the word before & after '_-_' with REGEX PowerShell使用 REGEX PowerShell 在 '_-_' 之前和之后获取单词
【发布时间】:2019-08-09 20:35:49
【问题描述】:

我试图在一个看起来像' - '的非保证字符串之后获取单词之前和十进制字符串。

考虑这个字符串

"some str (targetWord - 12434 trailing string)" 

这个字符串不保证在'-'之前或之后有空格 所以它可能看起来像以下之一

"some str (targetWord-12434 trailing string)" 
"some str (targetWord- 12434 trailing string)" 
"some str (targetWord -12434 trailing string)"
"some str (targetWord-  12434 trailing string)"  

到目前为止,我有以下内容

$allServices = (Get-Service "Known Service Prefix*").DisplayName
foreach ($service in $allServices){
  $service = $service.split('\((.*?)\)')[1]  #esc( 'Match any non greedy' esc)
  if($service.split()[0] -Match '-'){
    $arr_services += $service.split('( - )')[0..1]
  }else{
    $arr_services += ($service -replace '-','').split()[0..1]
  }
}

这适用于处理“-”和“-”的简单情况,但不能处理其他任何情况。我觉得这是可以由一行或最多两行 REGEX 处理的问题。

我想要结束的是一个字符串数组,其中偶数(包括零)是 targetWord,奇数是十进制字符串。

我的问题不是我不能做到这一点,而是它看起来像垃圾...... 我的意思是我的目标是尝试使用 REGEX 来获取每个单词,忽略“-”,然后将 targetWord 和 decimalString 推送到一个不断增长的数组中。

我认为这更像是一个谜题,并试图用它来提高我的 REGEX 技能。任何帮助表示赞赏!

【问题讨论】:

  • 您到底想从每个示例数据字符串中得到什么?
  • 数据应该是从我的服务器上运行的服务中提取的,它是由另一个应用程序填充的。左边的数据应该是客户端的实例名,右边是他们占用的端口。
  • 您可能需要将经过消毒但真实的示例数据以及正是您想要从每个示例字符串中添加到您的原始帖子中。 [grin] 查看我的答案,了解一种处理您发布的数据集的方法。

标签: regex powershell parsing


【解决方案1】:

传递给-match 运算符的单个regex 就足够了:

$arr_services = $allServices | ForEach-Object { 
  if ($_ -match '\((?<word>\w+) *- *(?<number>\d+)') { 
    # Output the word and number consecutively.
    $Matches.word, $Matches.number 
  }
}

# Output the resulting array.
$arr_services

请注意如何将管道输出作为数组直接收集在变量中 ($arr_services = ...) - 无需迭代地“添加”到数组。如果您需要确保 $arr_servicesalways 一个数组 - 即使管道仅输出 one 对象,请使用 [array] $arr_services = ...

使用您的示例字符串,以上产生(连续单词-数字对的平面数组):

targetWord
12434
targetWord
12434
targetWord
12434
targetWord
12434

至于正则表达式:

  • \( 匹配文字 (

  • \w+ 匹配在命名捕获组 word ((?&lt;word&gt;...) 中捕获的单词字符(\w - 字母、数字、_)的非空运行 (+)。

  •  *- * 匹配由任意数量的空格包围的文字 - - 包括没有空格 (*)。

  • \d+ 匹配一组非空数字 (\d),在命名组 digits 中捕获。

如果 -match 运算符找到匹配项,则结果将反映在 automatic $Matches variable 中,这是一个允许直接按名称访问命名捕获组的哈希表。

【讨论】:

  • 谢谢!这描述得非常好。不过我确实有一个问题。如果 -matches 返回 $true,“$Matches”是否作为描述字符串的内置变量?
  • @RedGrinGrumble:很高兴听到这个消息;是的,当-match 成功时(返回$true),$Matches 会自动填充 - 请参阅我刚刚添加到答案中的文档的链接。需要注意的是,如果 LHS 是 array-match 不再返回布尔值而是充当 filter,在这种情况下 $Matches填充。
【解决方案2】:

这是处理您发布的数据集的一种方法。它假定所有字符串都将具有与您发布的相同的一般格式。这意味着如果您的样本数据集不现实,它将失败。 [咧嘴一笑]

$InStuff = @(
    'some str (targetWord - 12434 trailing string)'
    'some str (targetWord-12434 trailing string)'
    'some str (targetWord- 12434 trailing string)'
    'some str (targetWord -12434 trailing string)'
    'some str (targetWord-  12434 trailing string)'
    )

$Results = foreach ($IS_Item in $InStuff)
    {
    $Null = $IS_Item -match '.+\((?<Word>.+) *- *(?<Number>\d{1,}) .+\)'
    [PSCustomObject]@{
        Word = $Matches.Word.Trim()
        Number = $Matches.Number
        }
    }

$Results

输出...

Word       Number
----       ------
targetWord 12434 
targetWord 12434 
targetWord 12434 
targetWord 12434 
targetWord 12434 

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-10
    • 2021-07-30
    • 2022-11-24
    相关资源
    最近更新 更多