将 "placeholder" 与 .NET 中的特定参数匹配

Match a "placeholder" with specific parameters in .NET

我正在尝试从文本中提取一些有用的数据(具有特定参数的占位符)(有些是原始文本,有些是 xml)。

有用的部分用其中之一分隔$, %, [], {}

下面的示例带有 $ 并显示了我感兴趣的不同可能内容。

 $EX1$                       -> EX1
 $EX2(a$b$c)$                -> EX2, (, a$b$c
 $EX3(abc\x/)$               -> EX3, (, abc\x/
 $EX4(\@\,/&/)$              -> EX4, (, \@\,/&/
 $EX5/X(Z)Y/$                -> EX5, /, X(Z)Y
 $EX6/X(ABC)/1$              -> EX6, /, X(ABC), 1
 $EX7/X\Z\/Y/$              -> EX7, /, X\Z\/Y
 $EX8/(A)/(B)/$              -> EX8, /, (A), (B)
 $EX9/(\$A$)\//(\$B$\/)/$  -> EX9, /, (\$A$)\/, (\$B$\/)

第一部分是占位符名称,可以选择后跟一些参数,例如 (...)/...//.../xx/.../.../ 其中 xx 是一个数字,... 可以是任何东西。

我已经构建了以下正则表达式 几乎可以完成这项工作,我想知道是否有改进它的方法,或者是否有另一种方法可以完成这项工作(它必须兼容使用 .NET 正则表达式引擎)

$
(?=[^$]{3,100}$)
(?<PH>[A-Za-z0-9:_-]{1,20})
(?:
  (?<C1>\/)
  (?<RX>(?:[^\\/\r\n]|\\/?)*)
  \/
  (?:
    (?<R>(?:[^\\/\r\n$]|\[\/$]?)*)
    \/
    |
    (?<G>\d*)
  )
  |
  (?:
    (?<C2>\()
    (?<F>(?:[^\t\r\n\f()]|\[()]?)*)
    \)
  )?
)
$

DEMO

这是正则表达式的 "improved" 版本,它使用 () 和 {} 的平衡组。捕获组命名为 "ph"、"FirstSep"、"value1"、"value2"、"value3"(为了测试简单,您可以根据需要重命名):

$
(?=[^$]{3,100}$)
(?<ph>[\w\:\-]+)
(?:(?<FirstSep>[\/\(\{])(?<value1>
    (?>
        [^{}()]+ 
        |    [\(\{] (?<number>)
        |    [\)\}] (?<-number>)
    )*
    (?(number)(?!))
)
[\)\}]
)?
(?:(?<FirstSep>/)
     (?<value2>
          \d+  |
          [^/\r\n\]*(?>\.[^/\r\n\]*)*
      )?
)?
(?:/
     (?<value3>[^/\r\n\]*(?>\.[^/\r\n\]*)*
      )?
)?
/?
$

在这里,您可以看到它现在捕获包含在 {} 或 () 中的子组:

$EX2(a($b)$c)$          --> EX2, (, a($b)$c 
$EX3{a({bc})\x/}$       --> EX3, {, a({bc})\x/

关于匹配带内部转义定界符的定界字符串的好信息:Finding quoted strings with escaped quotes in C# using a regular expression