使用 .NET 正则表达式查找所有特殊标记

Finding all special tokens with .NET regular expressions

使用正则表达式,我需要收集 valid 顶级标记 {...} 并忽略引用字符串中的标记边界"..."(包括可能的 "")。

简化样本:

TEXT{bbbbb}TEXT{cccc|{dddd}}TEXT{eeee|ff{gg}hh|ii{jj}"kk}{|{}ll""mm{nn}"oo|{pppp}}TEXT

预计有 3 场比赛:

  1. {bbbbb}
  2. {cccc|{dddd}}
  3. {eeee|ff{gg}hh|ii{jj}"kk}{|{}ll""mm{nn}"oo|{pppp}}
    请注意字符串 "kk}{|{}ll""mm{nn}" 的内容被忽略

每个标记都应遵循以下语法:

'{'<tokenName>[a1]['|'[a2|c1]('='|'<>')c2]['|'c3['|'c4]]'}'

其中 aX 是简单的正则表达式 ((,-?\d+(:.*)?|:.*)),cX 可以包含匹配的 {-}、纯文本和字符串 "..." 其中 {}|"" 等特殊字符被视为纯文本。

我不明白此正则表达式中需要的平衡和转义。对于初学者来说可能太难了。

其他详细信息:

我已经完成了部分解决方案,我的问题是平衡和引用。

我正在尝试创建包含在 input As String 中的扩展标记,它看起来类似于 format strings,但也允许条件评估。例如在文件名模板中使用这些标记,用户可以在批处理中配置文件名的自定义部分。令牌具有字母数字名称和格式部分(包括可选条件、真部分和假部分)。格式化部分可以在:

现在有效令牌的完整语法是:

'{'<tokenName>[quickFormat]['|'[complexFmt1]('='|'<>')value][complexFmt2|[complexFmt3]]'}'

我的代码使用了很多命名组,但正则表达式可能太简单了:

'*** matching token names (for later use as match.Group(groupName))
Const tokenGroup As String = NameOf(tokenGroup)
Const compareFormatGroup As String = NameOf(compareFormatGroup)
Const quickFormatGroup As String = NameOf(quickFormatGroup)
Const compareOperatorGroup As String = NameOf(compareOperatorGroup)
Const compareValueGroup As String = NameOf(compareValueGroup)
Const defaultFormatGroup As String = NameOf(defaultFormatGroup)
Const elseFormatGroup As String = NameOf(elseFormatGroup)

'*** subpatterns
Const nativeFormatSpec As String = "(,-?\d+(:.*)?|:.*)"
Const complexFormatSpec As String = "(" & nativeFormatSpec & "|.*({0.*}.*)*)" 'value allowing one token {0} multiple times

Dim matches As MatchCollection = Regex.Matches(input,
        $"\{{(?<{tokenGroup}>{Regex.Escape(token)})(?<{quickFormatGroup}>{nativeFormatSpec}?)" &
        $"((\|(?<{compareFormatGroup}>{complexFormatSpec}))?(?<{compareOperatorGroup}>=|!=|<>)(?<{compareValueGroup}>.*))?" &
        $"(\|(?<{defaultFormatGroup}>{complexFormatSpec})(\|(?<{elseFormatGroup}>{complexFormatSpec}))?)?\}}")

根据您的简化数据,这里是处理提取的正则表达式:

\{(?>(?:"[^"]*(?:""[^"]*)*"|[^{}]+)|\{(?<n>)|\}(?<-n>))*(?(n)(?!))\}

demo

这基本上是一个平衡的大括号正则表达式与 VB.NET 类似的字符串文字匹配正则表达式 "[^"]*(?:""[^"]*)*"。请注意,这部分 - (?:"[^"]*(?:""[^"]*)*"|[^{}]+) - 在查找配对大括号(带引号的字符串和非大括号)时实际上会被忽略。