PEG.js获取(和)之间的任何文本;

mot*_*son 1 javascript regex peg pegjs

我试图在最后用分号的parathesis之间捕捉一些文本.

例: (in here there can be 'anything' !"#¤);); any character is possible);

我试过这个:

Text
 = "(" text:(.*) ");" { return text.join(""); }
Run Code Online (Sandbox Code Playgroud)

但似乎(.*)将包括最后一个); 之前");" 我和我得到错误:

预期");" 或任何字符,但发现输入结束

问题是文本可以包含");" 所以我想要最外面的); 线路结束时决定.

这个正则表达式\((.*)\);做了我想要的,但我怎样才能在PEG.js中做同样的事情呢?我不想在结果中包含外括号和分号.

如果你知道你在做什么= P,这似乎应该很容易

pau*_*ens 6

因此,重点是PEG是确定性的,而正则表达不是.因此,一旦接受了一些输入,PEG就不会回溯.然后我们可以模拟你想要的语义.既然你说正则表达式\((.*)\);做你想要的,我们可能会把它翻译成PEG.

这个正则表达式做了什么?它会消耗所有字符直到输入结束,然后保持回溯直到它看到a );,即它消耗最后一个可能的字符);.

为了使这项工作与PEG一起使用,如果我们);提前做好,我们可能会使用前瞻来继续消费.

所以,一个解决方案是:

Text
 = "(" text:TextUntilTerminator ");" { return text.join(""); }

TextUntilTerminator
 = x:(&HaveTerminatorAhead .)* { return x.map(y => y[1]) }

HaveTerminatorAhead
 = . (!");" .)* ");"
Run Code Online (Sandbox Code Playgroud)

的TextUntilTerminator非末端消耗而HaveTerminatorAhead 比赛而不消耗它(先行的&符号).然后它消耗一个单个字符.它一直这样做,直到它知道我们已经达到);输入的最终结果.

在HaveTerminalAhead非终端很简单:它验证前方是否有一个字符,并且,如果这样做,garantees有至少一个);后.我们还使用负向前瞻!停止在);我们看到的第一个(避免消耗它,这将重现您的原始问题).

然后,此PEG再现您建议的正则表达式的行为.