正则表达式嵌套标签

问题描述:

我想通过函数标签解析以下文本正则表达式正则表达式嵌套标签

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

虽然我不建议通过正则表达式解决这一点,如果你真的想,你要告诉你的正则表达式不包括一个开始标记,如:

<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对!我完全忘了那个^^ –

关于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也有这方面的准备工具,但我不知道。