YS Regular Expressions
All modern programming languages have regular expressions.
YS has them too.
Perl was the first modern language to include them as a built-in feature.
YS regexes borrow quite a bit from Perl's, but also behave as functions that return matching results (unlike Perl, and more like all the others).
Let's take a look...
Basic Usage🔗
if word =~ /^[aeiou]/:
say: "'$word' starts with a vowel"
say: "'$word' doesn't start with a vowel"
So far, so Perl.
Our regex application operator is =~
and we defined a regex literal with the
/.../
syntax.
We can also use Perl's !~
operator to test for non-matching:
if word !~ /^[aeiou]/:
say: "'$word' doesn't start with a vowel"
say: "'$word' starts with a vowel"
Regex Results🔗
When a regex doesn't match, it returns nil
.
That way it can be used in a boolean context.
When it does match, it returns the match string.
$ ys -e '
defn main(word):
m =: word =~ /^[aeiou]/
say: "m = $m"
if m:
say: "$word starts with a vowel"
say: "$word doesnt start with a vowel"
' -- aardvark
m = a
aardvark starts with a vowel
Clojure Regexes🔗
Let's see how our last example compiles to Clojure.
$ ys -ce '
defn main(word):
m =: word =~ /^[aeiou]/
say: "m = $m"
if m:
say: "$word starts with a vowel"
say: "$word doesnt start with a vowel"
'
(defn
main
[word]
(let
[m (=-- word #"^[aeiou]")]
(say (str "m = " m))
(if
m
(say (str word " starts with a vowel"))
(say (str word " doesnt start with a vowel")))))
(apply main ARGS)
It looks like the =~
operator is compiled to =--
.
=--
works exactly like Clojure's re-find
function, except it cast the thing
being matched to a string.
$ ys -pe '1234 =~ /3/'
"3"
$ clj -M -e '(re-find #"3" 1234)'
class java.lang.Long cannot be cast to class java.lang.CharSequence
YS can run Clojure code directly using the -C
flag.
$ ys -Ce '
(defn main [word]
(let [m (re-find #"^[aeiou]" word)]
(say (str "m = " m))
(if m
(say (str word " starts with a vowel"))
(say (str word " doesnt start with a vowel")))))
(apply main ARGS)
' -- aardvark
m = a
aardvark starts with a vowel
We changed the =--
to re-find
just to show that it works the same way.
Capture Groups🔗
How do we capture parts of the match?
If the regex contains capture parens, a match will return a vector containing the complete match string followed by the captured groups.
This regex finds the parts of aardvark
that begin with v
up until the final
character:
$ ys -pe '("aardvark" =~ /(v.*?)(.)$/)'
["vark" "var" "k"]
Learn More🔗
The best place to go from here is to look at the Clojure docs for re-find
.
One final note.
YS provides an alternative to the /.../
syntax with the qr("...")
function:
$ ys -e 'say: /foo/ qr("bar")'
#"foo" #"bar"
Obviously the Clojure syntax for regex literals is #"..."
.
Later this week we'll talk about how YS and Clojure syntaxes differ, and why.