There are a variety of features which now exist in JAPE, such as a negative operator.
For example, you are no longer constrained to use the same annotation type in both parts of the conjunction, as long as you have GATE 5.0 or higher.
{Token.length == "3"} works with GATE version 4 and more
{Token.length == 3} works with GATE version 5 and more
{Token.length == "1", Token.kind == "word"} works with GATE version 4 and more
{Token.length == "1", SpaceToken.kind == "control"} works with GATE version 5 and more
{Token.length == "1", !SpaceToken.kind == "control"}
will match a single token of length 1 as long as it's not a SpaceToken of kind control. More info in the user guide.
{X contains Y}
returns true if an annotation of type X completely contains an annotation of type Y.
{X within Y}
returns true if an annotation of type X is completely covered by an annotation of type Y.
{X contains {Y.foo==bar}}
and
{X.f1 != "something", X contains {Y.foo=bar}}
and
{Lookup.majorType == have, !Lookup within {VG.tense == PrePer}}
({Token})[2,5]
matches between 2 and 5 consecutive tokens.