我正在寻找有关包含多级大括号的文字的帮助
例如,使用以下文字:
{{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#中做到这一点。
答案 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}) }
;
我正在写这篇文章; - )。
定义SeqNode
和BracesNode
以获取树。接下来遍历它,并计算你击中BracesNode的次数 - 当计数器显示“第一次”时,重新创建大括号,如果更多 - 忽略它们。
答案 2 :(得分:0)
您需要一个非正则表达式语法分析器才能将文本解析为一系列标记。有关编写此类解析器的建议,请参阅How to write a Parser in C#?。
与此相比,重新格式化令牌(可能通过二进制表达式树)应该相当简单。
答案 3 :(得分:0)
如果在大括号外面的操作符的优先级高于内部操作符的最低值,则保留大括号,否则删除它们