使用部分变量作为正则表达式字符串的一部分

Posted

技术标签:

【中文标题】使用部分变量作为正则表达式字符串的一部分【英文标题】:using a partial variable as part of regular expression string 【发布时间】:2022-01-20 12:17:30 【问题描述】:

我正在尝试遍历一组警报代码并使用正则表达式在 cpp 代码中查找它。我知道当我硬编码一个值并为我的正则表达式使用双引号时,我的正则表达式有效,但我需要传入一个变量,因为它是一个大约 100 个列表,可以使用单独的定义进行查找。以下是我一般要使用的内容。如何修复它以使其与 $lookupItem 一起使用,而不是在 Get-EpxAlarm 函数中硬编码“OTHER-ERROR”?我在 $fullregex 定义中尝试了 $lookupItem 周围的单引号和双引号,但它什么也不返回。

Function Get-EpxAlarm
  [cmdletbinding()]
  Param ( [string]$fileContentsToParse, [string]$lookupItem)
  Process
  
     $lookupItem = "OTHER_ERROR"
     Write-Host "In epx Alarm" -ForegroundColor Cyan

     # construct regex
     $fullregex = [regex]'$lookupItem', # Start of error message########variable needed
     ":[\s\Sa-zA-Z]*?=",             # match anything, non-greedy
     "(?<epxAlarm>[\sa-zA-Z_0-9]*)", # Capture epxAlarm Num
     '' -join ''
    
     # run the regex
     $Values = $fileContentsToParse | Select-String -Pattern $fullregex -AllMatches

     # Convert Name-Value pairs to object properties
     $result = $Values.Matches
     Write-Host $result

     #Write-Host "result:" $result -ForegroundColor Green

     return $result
  #process
#function


#main code

    ...
    Get-EpxAlarm -fileContentsToParse $epxContents -lookupItem $item
    ...

$fileContentsToParse 在哪里

        case OTHER_ERROR:
            bstrEpxErrorNum = FATAL_ERROR;
            break;

        case RI_FAILED:
        case FILE_FAILED:
        case COMMUNICATION_FAILURE:
            bstrEpxErrorNum = RENDERING_ERROR;
            break;

因此,如果我查找 OTHER_ERROR,它应该返回 FATAL_ERROR。

我在regex editor 中测试了我的正则表达式,它适用于硬编码值。如何定义我的正则表达式以便我使用参数并返回与硬编码参数值相同的内容?

【问题讨论】:

@SantiagoSquarzon 就像我在文章中所说的那样,我尝试了双引号,但它不像硬编码那样工作。它什么也不返回。 你说得对,我的错,我使用“OTHER_ERROR”对其进行了测试,它对我有用,但后来“RI_FAILED”不起作用。 你可以使用 ArgumentCompleter 来处理非常酷的情况 【参考方案1】:

我不建议尝试构建单个正则表达式来进行复杂的源代码解析 - 它很快就会变得非常难以阅读。

相反,编写一个小的错误映射解析器,它只逐行读取源代码并构建错误映射表:

function Get-EpxErrorMapping 
  param([string]$EPXFileContents)

  # create hashtable to hold the final mappings
  $errorMap = @
  # create array to collect keys that are grouped together
  $keys = @()

  switch -Regex ($EPXFileContents -split '\r?\n') 
    'case (\w+):' 
        # add relevant key to key collection
        $keys += $Matches[1] 
    'bstrEpxErrorNum = (\w+);' 
        # we've reached the relevant error, set it for all relevant keys
        foreach($key in $keys)
            $errorMap[$key] = $Matches[1]
        
    
    'break' 
        # reset/clear key collection
        $keys = @()
        
  

  return $errorMap

现在您需要做的就是调用此函数并使用结果表来解析$lookupItem 值:

Function Get-EpxAlarm
  [CmdletBinding()]
  param(
    [string]$fileContentsToParse,
    [string]$lookupItem
  )

  $errorMap = Get-EpxErrorMapping $fileContentsToParse

  return $errorMap[$lookupItem]

现在我们可以得到相应的错误码了:

$epxContents = @'
case OTHER_ERROR:
    bstrEpxErrorNum = FATAL_ERROR;
    break;

case RI_FAILED:
case FILE_FAILED:
case COMMUNICATION_FAILURE:
    bstrEpxErrorNum = RENDERING_ERROR;
    break;
'@

# this will now return the string "FATAL_ERROR"
Get-EpxAlarm -fileContentsToParse $epxContents -lookupItem OTHER_ERROR

【讨论】:

这对我不起作用。当我写主机“找到它:$errorMap[$lookupItem]”时,它会打印:找到它:System.Collections.Hashtable[HOP_PRT_NO_MEMORY]。此外,Write-Host $errorMap 什么也不打印。 你需要Write-Host "found it: $($errorMap[$lookupItem])"。谢谢@SantiagoSquarzon,已修复 我尝试了 Write-Host “找到它:$(...)”,找到它后它仍然没有打印任何内容 @SantiagoSquarzon 现在正在打印哈希表内容!谢谢! @Michele 您可以使用 $lookupItem.Trim() 删除前导和尾随空格(因此,Write-Host "error map: $($errorMap[$lookupItem.Trim()])")。

以上是关于使用部分变量作为正则表达式字符串的一部分的主要内容,如果未能解决你的问题,请参考以下文章

Python - 正则表达式作为目录路径的一部分 - 转义

如何使用正则表达式提取部分字符串

正则表达式替换字符串逗号的一部分

scanf中的正则表达式?

如何在正则表达式公式中包含括号作为谷歌表格中公式的一部分

如何在 C++ 的正则表达式中使用变量? [关闭]