正则表达式嵌套标签

时间:2017-02-17 09:53:36

标签: c# regex nested tags

我想通过函数标记用 Regex 解析以下文本。

git revert -m 2 [merge commit id]

下面是一个递归方法,应该将给定的文本转换为:

答案:44。     谢谢你的时间。     再见100雷克斯。

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

问题是,在嵌套标记的情况下,我的正则表达式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); } } 将在函数标记结束的第一次出现时停止。

我附上了一张图片,以便更清楚。

enter image description here

2 个答案:

答案 0 :(得分:3)

虽然我不建议通过RegEx解决这个问题,但如果你真的想要,你必须告诉你的Regex不要包含另一个开头标记,例如:

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

警告:表现糟糕,仅限教育用途!

另外,你应该逃避你的意见:

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

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

这不会解释很多现实的用例,所以再次说明:在这种特殊情况下,我不建议使用RegEx。

Online-Demo
Fiddle

答案 1 :(得分: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();

然后你可以用正则表达式或简单的字符串替换替换所有标签(删除括号之间的所有内容&lt;&gt;)。也许,XML Linq也有一个现成的工具,但我不知道。