如何减少文本中多层次的大括号

时间:2013-11-06 12:47:24

标签: c# .net algorithm

我正在寻找有关包含多级大括号的文字的帮助

例如,使用以下文字:

{{abc|{cde|fgh}} bb|cc}

我想获得

{abc bb|cde bb|fgh bb|cc}

并使用此

pp {vv {ff|ii|nn|aa} | {ee|hh|rr} } xx {{abc|{cde|fgh} bb|cc}

结果是

pp {vv ff|vv ii|vv nn|vv aa | ee|hh|rr} xx {abc bb|cde bb|fgh bb|cc}

这个想法是将文本放在几个级别的括号上,只有一个级别的大括号​​。

我该怎么做? 我想在C#中做到这一点。

4 个答案:

答案 0 :(得分:1)

我只是给你基本的想法,而不是为你编写代码。

在最外层的{}内部(a {b} c {d})内建立一个字符串的每一部分树(好的,树的一种)({b}将有2棵树 - 一个用于{d}和一个{a {b|c} d e | f})。跟在另一个元素后面的每个元素必须是该元素的子元素。每当有多个选项时,每个选项都必须是前一个节点的子节点,并且每个选项必须将下一个节点作为子节点。

因此,例如, -> b - / \ -> a - -> d -> e / \ / / -> c - \ \ -> f ,你有:

-> a -> b -> d -> e

然后使用depth-first search生成来自根的所有路径。

路径为-> a -> c -> d -> e-> f{a b d e | a c d e | f}
所以我们有{}

实施提示:

stack可能是跟踪节点的好主意。

{{a|b} {c|d}}之前和之后有空白的中间节点可能是明智的(相信我,这会使它更容易实现)。

所以 -> a - -> c - / \ / \ -> . - -> . - -> . \ / \ / -> b - -> d - 看起来像是:

{{1}}

答案 1 :(得分:1)

Lexer规则(我使用NLT格式):

"|" -> PIPE;
/[a-z]+/ -> ID;
/[ ]+/ -> WS;
"{" -> LBRACE;
"}" -> RBRACE;
%EOF -> EOF;

解析器:

s -> n:node { n };
node -> (PIPE- n:node)+ { new SeqNode("|",n) }
      | (WS- n:node)+ { new SeqNode(" ",a) }
      | LBRACE n:node RBRACE { new BracesNode(seq) }
      | id:ID { new SeqNode("",new string[]{id}) }
      ;  

我正在写这篇文章; - )。

定义SeqNodeBracesNode以获取树。接下来遍历它,并计算你击中BracesNode的次数 - 当计数器显示“第一次”时,重新创建大括号,如果更多 - 忽略它们。

答案 2 :(得分:0)

您需要一个非正则表达式语法分析器才能将文本解析为一系列标记。有关编写此类解析器的建议,请参阅How to write a Parser in C#?

与此相比,重新格式化令牌(可能通过二进制表达式树)应该相当简单。

答案 3 :(得分:0)

如果在大括号外面的操作符的优先级高于内部操作符的最低值,则保留大括号,否则删除它们