正则表达式难题 - PowerShell(.NET正则表达式引擎)

时间:2013-08-23 06:45:13

标签: .net regex powershell

背景

我有一个PowerShell脚本,我用它来处理一些XML文件。这些XML文件嵌入了'令牌''过滤器'。令牌在我的脚本中解析,过滤器应用于前面令牌评估的已解析值。

令牌定义如下:

{#!T#TokenName#T#!}

过滤器的定义如下:

{#!F#FILTERNAME#F#!}

某些令牌和过滤器有'参数',所有参数都在自己的参数标记中,所有参数必须明确命名,三个相等字符单独的参数名称和参数值:

{!P | PARAMNAME === ParamValue P |!}

例如,以下'RegVal'令牌有两个参数'RegKey'和'Name':

{!#T#RegVal {!#P#RegKey === RegKeyPath#P#!} {!#P#Name === RegValName #P#!}#T#!}


问题

我已经有了一个使用参数处理标记和过滤器的工作系统(在我从封闭的XML标记中提取字符串之后)。我首先使用正则表达式识别单个令牌,如下所示。

(?si){!#T#((?:(?!{!#T#.*#T#!}).)*)#T#!}

...问题是我现在想在其他令牌中嵌入令牌,例如:

{#T#ContainingToken {P | PARAMNAME === {#T#REGVAL {P | REGKEY === HKLM:!!!\ SOFTWARE \密押P |} {# P#名称===的TestEntry P |!}#T#!}·P#!}#T#!}

上面的正则表达式不合适,我不是正则表达式专家,我在上面的正则表达式上遇到了麻烦,所以是时候寻求帮助了。

我认为通过调整后的正则表达式可以实现这一目标吗?以下限制是完全可以接受的:

- 只有一个深度。

- 只嵌入参数值(所以在:===之后)

- 参数的第二次传递,以显示任何包含的标记和过滤器。

对于ref,这里是PowerShell片段:

function Get-Matches($pattern)
{
    begin { 
        Try {
            $regex = New-Object Regex($pattern)
        }
        Catch {
            Throw "Get-Matches: Pattern not correct. '$pattern' is not a valid regular expression."
        }
    }
    process { 
        foreach ($match in ($regex.Matches($_)))
        {
            ([Object[]]$match.Groups)[-1].Value
        }
    }
}

function Get-ParsedInput([String] $rawValue)
{
    $intermediateValue = $rawValue  
    $tokenMatches = @($intermediateValue | Get-Matches '(?si){!#T#((?:(?!{!#T#.*#T#!}).)*)#T#!}') # Wrapped as array...
    if ($tokenMatches.Count -gt 0)
    {
        $i=1
        $tokens = @{ }

        foreach ($tokenTextWithParms in $tokenMatches)
        {
            # ...from here I instantiate new token instance...

2 个答案:

答案 0 :(得分:1)

对于嵌套模式 - 通常正则表达式不是那个工具,因为它们源于无法处理“计数”的语法。但是在.NET中(因此也在PowerShell中)它可能是可能的。看看http://blogs.msdn.com/b/bclteam/archive/2005/03/15/396452.aspx。可能还有其他来源,但这是我第一次跑过去。

答案 1 :(得分:0)

基于此博客文章中的第二个示例......

http://blog.stevenlevithan.com/archives/balancing-groups

我最终得到了这个:

(?x)的 {!#T# (     ?(大于         (?!{!#T#|#T#!})。     |         {!#T#(?)     |         #T#!}(?< -Depth>)     )*     (?(深度)(?!)) ) #T#!}

......似乎工作得很充分,但目前不是100%的原因!