Skip to content

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 External link .

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.

Comments