Skip to content

Pattern matching

Selectors that accept strings for arguments can also accept a pattern to match their value. Patterns must follow Rust's Regular Expression rules.

This applies to (id), (str) and to every selector that accepts either as an argument

Matching by patterns is useful when you don't know the exact value to search for. Even when you do know all the possible values, it might be impractical to enumerate them.

For example, it would be annoying to have to do this:

clojure
(:or "productUser"
     "productUsers"
     "groupUser"
     "groupUsers")
(:or "productUser"
     "productUsers"
     "groupUser"
     "groupUsers")

When really all you want could be expressed as (group|product)Users?.

To specify a pattern, wrap the value with / (forward slash) on either end. For example, to match either identifier "a" or "b" using the same selector:

clojure
(id /^[ab]$/)
(id /^[ab]$/)

In this example, we could've achieved the same effect using (:or):

clojure
(:or (id a) (id b))
(:or (id a) (id b))

But what if we didn't know what a and b are? Consider this more realistic scenario where we're looking for all JSX components that specify data-??? attributes -- a pattern can help us match them even though we only know a subset of their name:

clojure
(jsx _ (attr /^data-/))
(jsx _ (attr /^data-/))

This would match <Foo data-key="..." /> and <Bar data-testid="..." /> and any attribute starting with data-.

Copyright © 2022-present Semantic Works, Inc.