簡體   English   中英

c#正則表達式與平衡組沒有響應

[英]c# regex with balancing groups not responding

我有以下代碼:

void Main()
{
  string template = @"
aaa 
{begin iteration items} 
  bbbbbb 
  {begin iteration subitems} 
    ccccccc 
  {end iteration subitems} 
  ddddddddd 
  {begin iteration items} 
    hhhhhhhhhhhhhhhhh
  {end iteration items} 
  iiiiiiiiiiiiiiiiiiiiiiiiiiii
{end iteration items} 
eeeeeeeeeeeeeeee
{begin iteration items} 
  ffffff
{end iteration items} 
gggggggggggg
  ";

  string re = @"
\{\s*begin\s+iteration\s+items\s*}
(?<template>
  (
    (?<iteration>\{\s*begin\s+iteration\s+items\s*})
    |(?<-iteration>\{\s*end\s+iteration\s+items\s*})
    |((?!(\{\s*begin\s+iteration\s+items\s*})|(\{\s*end\s+iteration\s+items\s*})).*?)
  )*(?(iteration)(?!))
)
\{\s*end\s+iteration\s+items\s*}
  ";

  Regex r = new Regex(re, RegexOptions.IgnoreCase | RegexOptions.Singleline | RegexOptions.IgnorePatternWhitespace);
  var matches = r.Matches(template);
  matches.Dump();
}

template平衡時,返回匹配項,一切正常。 但是,當我在模板中的iiiiiiiiiiiiiii行之后將{end iteration items}更改為{end1 iteration items} ,代碼停止響應matches.Dump()行( Dump()是在 LinQPad 中讀取/枚舉的擴展方法)

怎么了? 是否可以重寫 Regex 以使其始終響應?

編輯我的目標是在語法有效時捕獲所有頂級<template>組,否則不捕獲任何內容。 我按照盧卡斯的建議嘗試了非回溯組,但現在語法有效時沒有捕獲。

您在這里遇到了災難性的回溯

簡而言之:具有嵌套量詞的((something)*)*形式的模式將觸發它,因為如果無法立即找到匹配項,引擎必須嘗試所有可能的組合。

您可以使用原子組來防范它。 以下應該可以解決問題:

\{\s*begin\s+iteration\s+items\s*}
(?<template>
  (?>
    (?<iteration>\{\s*begin\s+iteration\s+items\s*})
    |(?<-iteration>\{\s*end\s+iteration\s+items\s*})
    |[^{]+
    |\{
  )*(?(iteration)(?!))
)
\{\s*end\s+iteration\s+items\s*}

如果需要捕獲,或者使用((?> ... ))而不是(?> ... )

我簡化了表達式 - 使用原子組時不再需要前瞻,因為這些情況將由iteration組處理。 替代方案的最后一部分 ( \\{ ) 在這里是為了說明單獨的左大括號,它們不是開始/結束序列的一部分。 大部分文本被原子組內的[^{]+消耗,因此回溯不會發生。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM