Use negative prediction predicates:
phrase =(!"START" .)* "START" result:(!"END" .)* "END" .* { for (var i=0;i<result.length;++i) // remove empty element added by predicate matching {result[i]=result[i][1]; } return result.join(""); }
You need to use a negative predicate for END as well as START, because repetition in pegjs is greedy.
Alternatively, the action can be written as
{return result.join("").split(',').join("");}
Although this depends on the not necessarily documented behavior of join when working with nested arrays (namely, that it joins subarrays with commas and then concatenates them). C>
[UPDATE] A shorter way to handle empty elements is
phrase =(!"START" .)* "START" result:(t:(!"END" .){return t[1];})* "END" .* { return result.join(""); }
ebohlman
source share