使用嵌套分隔符解析字符串

时间:2013-08-09 18:21:30

标签: .net regex

我正在尝试制作一个可以给我以下结果的正则表达式:

文本:

  

[添加月份([实际日期],5)] - 另一个文本 - [实际日期] - [Cria ocorrencia padrao.Record.Name] - 另一个文本 - [添加月份([实际日期],5,[实际]日期])] - [添加月份(添加天数(添加日期([实际日期],5),7),5,[实际日期])] - 最终文本

期望的输出:

Match 1: [Add Months([Actual Date], 5)]
Match 2:  - Another Text - 
Match 3: [Actual Date]
Match 4:  - 
Match 5: [Cria ocorrencia padrao.Record.Name]
Match 6:  - Another Text - 
Match 7: [Add Months([Actual Date], 5, [Actual Date])]
Match 8:  - 
Match 9: [Add Months(Add Days(AddDays([Actual Date], 5), 7), 5, [Actual Date])]
Match 10: - final text

但我没有成功,我需要完成这项任务。

我正在尝试使用此正则表达式在.Net中使用嵌套模式正则表达式:

string pattern = @"(([^\[\]]*)??)|(\[(?>\[(?<DEPTH>)\](?<-DEPTH>)|.?)*(?(DEPTH)(?!))\])?([^\[\]]*)";

但是不工作,有人可以给我一个亮点吗?

谢谢。

2 个答案:

答案 0 :(得分:3)

使用平衡组的常用方法是:

\G
(?:
  [^\[\]]+
|
  \[
  (?>
    [^\[\]()]
  |
    (?<Depth>[(\[])
  |
    (?<-Depth>[)\]])
  )*
  (?(Depth)(?!))
  \]
)

Working demo.

有关我是如何到达那里的详细说明,请参阅this post。请注意,在您的情况下,我添加了\G锚点以确保所有匹配都是相邻的,并且第一次更改不会意外地获取括号内容。

很抱歉,我无法真正破译您的模式 - 自由间距(或在.NET RegexOptions.IgnorePatternWhitespace中)有很大帮助。

如果您知道您的输入始终是正确嵌套的,那么这就是所需要的。如果您的输入可以包含转义的括号/括号或错误嵌套的括号/括号,那么此模式将为您提供一些不需要的结果,并且您必须更加努力,以确保始终关闭右括号。 (请参阅链接演示中的第二行 - 内部括号以错误的顺序关闭,但它们仍然匹配。)

您可以做的是:每当您打开一个开口支架时,将其相应的关闭悬挂物推到捕捉堆叠上,而不是打开支架本身。您可以通过前瞻来做到这一点,这样您就不会陷入字符串中的位置。然后,如果当前字符与相应的字符匹配(使用简单的反向引用),则只减小深度计数器。

\G
(?:
  [^\[\]]+
|
  \[
  (?>
    [^\[\]()]
  |
    [(](?=.*(?<Close>[)]))
  |
    \[(?=.*(?<Close>\]))
  |
    (?<-Close>\k<Close>)
  )*
  (?(Close)(?!))
  \]
)

Working demo

当然,这仍然无法解决问题。

答案 1 :(得分:0)

我找到了解决问题的模式:\[(?>\[(?<DEPTH>)|\](?<-DEPTH>)|.?)*(?(DEPTH)(?!))\]|([^\[\]]*)

在本文中: [添加月份([实际日期],5)] - 另一个文本 - [实际日期] - [Cria ocorrencia padrao.Record.Name] - 另一个文本 - [添加月份([实际]日期],5,[实际日期])] - [添加月份(添加天数(添加日期([实际日期],5),7),5,[实际日期])] - 最终文本

返回我:

Match 1: [Add Months([Actual Date], 5)]
Match 2:  - Another Text - 
Match 3: [Actual Date]
Match 4:  - 
Match 5: [Cria ocorrencia padrao.Record.Name]
Match 6:  - Another Text - 
Match 7: [Add Months([Actual Date], 5, [Actual Date])]
Match 8:  - 
Match 9: [Add Months(Add Days(AddDays([Actual Date], 5), 7), 5, [Actual Date])]
Match 10: - final text