2017-02-17 169 views
0

我想通過函數標籤解析以下文本正則表達式正則表達式嵌套標籤

Anwers: <function>2+2 
       <function>1+3</function> 
     </function>. 
Thanks for your time. 
<function>sayGoodbye() 
     <function>10*10</function> 
     writeYourName() 
</function> 

下面是應該改變給定文本遞歸方法:

答案:44。 謝謝你的時間。 再見100雷克斯。

private static readonly string TagFormulaStart = "<function>"; 
private static readonly string TagFormulaEnd = "</function>"; 

public static string Calculate(string formula) 
{ 
    var pattern = string.Format("{0}(((.|\r|\n)*?)){1}", TagFormulaStart, TagFormulaEnd); 
    var matches = Regex.Matches(formula, pattern); 

    if (matches.Count == 0) 
    { 
     return formula; 
    } 
    else 
    { 
     var firstAppearanceOfTAG = matches[0].ToString(); 
     var formulaToCalculate = firstAppearanceOfTAG.Replace(TagFormulaStart, string.Empty).Replace(TagFormulaEnd, string.Empty); 
     var result = BgProcessorLib.Evaluator.EvaluateString(formulaToCalculate, null, false); 

     formula = formula.Replace(firstAppearanceOfTAG, result); 

     return Calculate(formula); 
    } 
} 

的問題是,我的正則表達式/<function>(((.|\r|\n)*?))<\/function>/igm嵌套的標籤的情況下,將在功能標籤結束的第一次出現停止。

我附上了一張照片,使其更清晰。

enter image description here

+1

如果您使用C#並使用.NET正則表達式,則在僅支持JS正則表達式的站點上測試正則表達式毫無意義。 –

+2

您確定要用正則表達式解析XML嗎?有很多準備好的「輪子」,調用XML解析器。 –

+0

@NikolayProkopyev它不是一個XML。 – POIR

回答

3

雖然我不建議通過正則表達式解決這一點,如果你真的想,你要告訴你的正則表達式不包括一個開始標記,如:

<function>((?!<function>).)*?<\/function> 

警告:可怕的表現,僅用於教育目的!

此外,你應該逃避你輸入:

var pattern string.Format("{0}((?!{0}).)*?{1}", 
    Regex.Escape(TagFormulaStart), 
    Regex.Escape(TagFormulaEnd)); 

var matches = Regex.Matches(formula, pattern, RegexOptions.Singleline); 

這不會佔很多逼真的使用情況,如此反覆:我不建議在這種特殊情況下使用正則表達式。

Online-Demo
Fiddle

+3

「Educational」提示:從不在模式中使用'(。| \ r | \ n)*?'。只需使用'RegexOptions.Singleline',一個簡單的'.'將匹配任何字符。 –

+0

@WiktorStribiżew對!我完全忘了那個^^ –

0

關於XML的方法。

首先,使您的源代碼有效的XML,即添加周圍的<root> Answer <function... </root>根標記。

然後使用解析器像Linq

XElement root = XElement.Parse(sourceString); 

foreach (var funct in root.Descendants("function")).ToList() { 
    var evaluated = evaluate(funct.InnerText); // evaluate should be defined before 
    funct.InnerText = evaluated; 
} 

var result = root.ToString(); 

然後只需更換了與正則表達式或簡單字符串的所有標籤替換(刪除括號<之間的所有內容>)。也許,XML Linq也有這方面的準備工具,但我不知道。