我试图在最后用分号在并列之间捕获一些文本。

示例:(in here there can be 'anything' !"#¤);); any character is possible);
我试过这个:

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

但似乎 (.*) 将包括最后一个 );前 ”);”确实,我得到了错误:



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

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

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

最佳答案

因此,重点是 PEG 是确定性的,而正则表达式则不是。因此,一旦接受某些输入,PEG 就不会回溯。然后我们可以模拟你想要的语义。由于您说正则表达式 \((.*)\); 可以满足您的需求,我们可能会将其转换为 PEG。

这个正则表达式有什么作用?它消耗所有字符直到输入结束,然后继续回溯直到看到 ); ,即消耗最后一个可能的 );

为了使用 PEG 进行这项工作,我们可能会使用前瞻来继续消费,如果我们有一个 ); 前面。

所以,一个解决办法是:

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

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

HaveTerminatorAhead
 = . (!");" .)* ");"
TextUntilTerminator 非终端消耗,而 HaveTerminatorAhead 匹配而不消耗它(前瞻,& 符号)。然后它消耗一个字符。它会一直这样做,直到它知道我们已经达到了输入的最终 );
HaveTerminalAhead 非终结符很简单:它验证前面是否有一个字符,如果是,则保证后面至少有一个 );。我们还使用负前瞻 ! 在我们看到的第一个 ); 处停止(避免使用它,这会重现您的原始问题)。

然后,此 PEG 会重现您建议的正则表达式的行为。

关于javascript - PEG.js 获取 ( 和 ) 之间的任何文本;,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/39604207/

10-12 05:35