背景
我有一个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...
答案 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%的原因!