Course of Raku / Addendum 🆕 / Types and text machines / Regexes and grammars / Exercises / Validate identifiers
Solution: Validate identifiers
Here is a possible solution to the task.
Code
for <count total2 2fast my-var _hidden> -> $name {
my $ok = $name ~~ / ^ <[A..Za..z_]> <[A..Za..z0..9_]>* $ /;
say "$name: { $ok ?? 'valid' !! 'invalid' }";
}🦋 You can find the source code in the file validate-identifier.raku.
Output
count: valid
total2: valid
2fast: invalid
my-var: invalid
_hidden: validComments
The anchors
^and$force the pattern to cover the whole string, so a single stray character like the hyphen inmy-varmakes it invalid.The first character class allows a letter or underscore; the second, repeated with
*, additionally allows digits — matching the classic identifier rule exactly.The second class can also be written as
\w, the built-in shorthand for a word character (a letter, a digit, or an underscore):my $ok = $name ~~ / ^ <[A..Za..z_]> \w* $ /;
One difference to be aware of:
\win Raku is Unicode-aware, so a name such ascaféalso passes — which happens to match Raku itself, wheremy $café = 1;is perfectly legal. The spelled-out class<[A..Za..z0..9_]>keeps the check strictly ASCII.There is a twist, though: in Raku itself
my-varis a valid identifier! Raku allows a hyphen (or an apostrophe, as inisn't) inside a name, as long as it is followed by a letter — which is why subroutines likeis-primeread so naturally. To validate Raku identifiers, allow such groups after the classic part:for <count total2 2fast my-var _hidden> -> $name { my $ok = $name ~~ / ^ <[A..Za..z_]> \w* [ '-' <[A..Za..z]> \w* ]* $ /; say "$name: { $ok ?? 'valid' !! 'invalid' }"; }
Each bracketed group
[ '-' <[A..Za..z]> \w* ]accepts a hyphen only when a letter follows, somy-varis now reported as valid, while2fast— and strings likea-ora-1— still are not.