Consider the following toy example: I have a set of language sounds, which I partition into two exclusive subsets, consonants and vowels. I want to set up string patterns for e.g. StringMatchQ
that may contain restrictions based on the sound specification. For sake of simplicity, I used letters instead of sounds, as for now it does not matter.
(* Define domains *)
vowels = {"a", "e", "i", "o", "u"};
consonants = {"b", "c", "d", "f", "g"};
(* Define predicates *)
VowelQ[x_] := MemberQ[vowels, x];
ConsonantQ[x_] := MemberQ[consonants, x];
(* Use predicates in pattern matcher *)
StringReplace["badge",
Shortest[pre__] ~~ c : __?ConsonantQ ~~ v_?VowelQ ~~ EndOfString :>
pre <> "-[" <> c <> "]-[" <> v <> "]"]
"ba-[dg]-[e]"
My question is:
How to set up domains that can be used like e.g. DigitCharacter
in the pattern matcher,
that is, how to define Consonant
and Vowel
in the following (putative) application to yield the same result as the above code?
StringReplace["badge",
Shortest[pre__] ~~ c : Consonant .. ~~ v : Vowel ~~ EndOfString :>
pre <> "-[" <> c <> "]-[" <> v <> "]"]
I can define new data structures, like Consonant["c"]
, that is displayed as "c"
, but is nevertheless interpreted as Consonant["c"]
, though I have the feeling that this is not the way to do it.