Operators

Repetition

There are several operators for defining repetition of matchers. All repetition specifiers are written after the repeated element, and none of them can be used as replacers.

Optional

Optional elements are either present or not present and are written as ?.

rule optional = 'a' -> 'b' in # 'c'? _;

This rule will replace all occurrences of a in the input that are either at the beginning of a word or after a word-initial c.

Arbitrary-Length Repetitions

The + and * operators will match any number of occurrences of the matcher they’re attached to, with + requiring at least one and * also matching nothing.

rule merge_as = 'a'+ -> 'a';

This will match any number of a and merge them into a single one.

Note that repetition will repeat the matcher, not the matched symbol. This means that .+ will match any sequence of symbols, and therefore will match the entire word. We will cover how to match repeats of the same character in More on Bindings.

Specific Length Repetitions

You can also specify a specific minimum and maximum number of repetition using curly braces. {m-n} matches between m and n times, where m and n must be replaced with fixed numbers.

rule 'a' -> 'b' in # {2-4} _;

This will replace a with b if it is between the 3rd and 5th position in the word (inclusive).

Not

The not operator !, written before a matcher, will match a single symbol if the matcher it is attached to doesn’t match at a position.

rule not_a -> !'a' -> 'b';

Will replace all symbols except a with b, so sad is transformed to bab.

Conjunction Operators

Conjunction (And)

Sometimes, you may want to match on multiple conditions at the same times. For example, you might want to match any number of consonants, the first of which is not b. This can be written with the conjunction operator & as

rule cons_not_b = cons+ & !'b' -> ();

This operator always uses the size of the match on the left side, so there’s no need to “fill in” anything on the right side of the !'b'. As long as it matches in the same position, the expression matches.

Strict Conjunction

There is a variant of this operator called the strict conjunction, written &&, which does require both matches to be the same size. For example, to match any number of consonants where neither the first nor the last is a b, you could use this operator and write

rule cons_not_b_2 = cons+ && !'b' .* !'b' -> ();

Widen

Next, the widen operator << tries to find a match for the right side which completely encompasses the left side match. One key application of this is to extract syllable information associated with a symbol:

rule a_in_stressed = 'a' << [[+stress]] -> 'e';

See the chapter on syllables for more information on syllable feature matchers.

Narrow

Finally, there is the narrow operator >> which looks for a match to the right side only inside the left side match. So, to match any instances of b which are in a sequence of between 2 and 4 consonants, the following could be used:

rule b_in_cluster = cons{2-4} >> 'b' -> ();

For compatibility reasons, this operator works slightly differently than the other related operators (it was originally intended to also cover the use of the newer widen operator) and returns its right side match. If you need the match within the span of another matcher while still returning the full match, this can be worked by matching any additional symbols using wildcards, such as:

rule b_in_cluster = cons{2-4} >> (.* 'b' .*) -> ();