如何匹配块的开始和结束 [英] How to match the start and end of a block

查看:144
本文介绍了如何匹配块的开始和结束的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想定义一个特殊的代码块,它可以由 {[<#]的字符的任意组合开始,结束将是

 

{
block-content
}

{##
block-content
##}

#[[< {###
block-content
###}>]]#

可以使用 petitparser-dart 吗?

解决方案

是的,可以回引用,但不是那么简单。



首先,我们需要一个可以反转分隔符的函数。我想出了以下:

  String reverseDelimiter token $ {
return token.split('')。reversed.map((char){
if(char =='[')return']';
if(char = ='{')return'}';
if(char =='<')return'>';
return char;
})。
}

然后我们必须声明 stopDelimiter 解析器。它在这一点上是未定义的,但是一旦我们知道它就会被真正的解析器替换。

  var stopDelimiter = undefined(); 

startDelimiter 的操作中, stopDelimiter 与动态创建的解析器如下:

  var startDelimiter = pattern('#< {[')。plus()。flatten()。map((String start){
stopDelimiter.set(string ());
return start;
});

其余部分不重要,但取决于您的确切需求:

  var blockContents = any()。starLazy(stopDelimiter).flatten 
var parser = startDelimiter& blockContents& stopDelimiter;

上面的代码定义了 blockContents 它读取任何东西,直到遇到匹配的 stopDelimiter 。提供的示例通过:

  print(parser.parse('{block-content}') ); 
// Success [1:18]:[{,block-content,}]

print(parser.parse('{## block-content ##}'));
//成功[1:22]:[{##,block-content,##}]

print(parser.parse('#[[< {### block-content ###}>]]#'));
// Success [1:32]:[#[[< {###,block-content,###}>]]#]
/ pre>

如果你想嵌套解析器,上面的代码不工作。如果需要,可以通过记住上一个 stopDelimiter 并恢复该问题来避免该问题。


I want to define a special code block, which may starts by any combination of characters of {[<#, and the end will be }]>#.

Some example:

{
    block-content
}

{##
    block-content
##}

#[[<{### 
    block-content 
###}>]]#

Is it possible with petitparser-dart?

解决方案

Yes, back-references are possible, but it is not that straight-forward.

First we need a function that can reverse our delimiter. I came up with the following:

String reverseDelimiter(String token) {
  return token.split('').reversed.map((char) {
    if (char == '[') return ']';
    if (char == '{') return '}';
    if (char == '<') return '>';
    return char;
  }).join();
}

Then we have to declare the stopDelimiter parser. It is undefined at this point, but will be replaced with the real parser as soon as we know it.

var stopDelimiter = undefined();

In the action of the startDelimiter we replace the stopDelimiter with a dynamically created parser as follows:

var startDelimiter = pattern('#<{[').plus().flatten().map((String start) {
  stopDelimiter.set(string(reverseDelimiter(start)).flatten());
  return start;
});

The rest is trivial, but depends on your exact requirements:

var blockContents = any().starLazy(stopDelimiter).flatten();
var parser = startDelimiter & blockContents & stopDelimiter;

The code above defines the blockContents parser so that it reads through anything until the matching stopDelimiter is encountered. The provided examples pass:

print(parser.parse('{ block-content }')); 
  // Success[1:18]: [{,  block-content , }]

print(parser.parse('{## block-content ##}')); 
  // Success[1:22]: [{##,  block-content , ##}]

print(parser.parse('#[[<{### block-content ###}>]]#'));
  // Success[1:32]: [#[[<{###,  block-content , ###}>]]#]

The above code doesn't work if you want to nest the parser. If necessary, that problem can be avoided by remembering the previous stopDelimiter and restoring it.

这篇关于如何匹配块的开始和结束的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆