1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
|
10.3 Pattern Matching
# Pattern Matching
When getting and setting information into the Time State, it's possible
to use more complex keys than basic symbols such as `:foo` and
`:bar`. You can also use URL style strings called paths such as
`"/foo/bar/baz"`. Once we start working with paths, we can then start
taking advantage of Sonic Pi's sophisticated pattern matching system to
`get` and `sync` with 'similar' rather than 'identical' paths. Let's
take a look.
## Match any path segment
Let's assume we want to wait for the next event that has three path segments:
```
sync "/*/*/*"
```
This will match any Time State event with exactly three path segments,
regardless of their names. For example:
* `cue "/foo/bar/baz"`
* `cue "/foo/baz/quux"`
* `cue "/eggs/beans/toast"`
* `cue "/moog/synths/rule"`
However, it will *not* match paths with fewer or more path segments. The
following will not match:
* `cue "/foo/bar"`
* `cue "/foo/baz/quux/quaax"`
* `cue "/eggs"`
Each `*` means *any content*. So we could match paths with just one segment with `/*` or paths with five segments with `/*/*/*/*/*`
## Matching partial segments
If we know what the segment is going to start or finish with, we can use
a `*` in addition to a partial segment name. For example:
`"/foo/b*/baz"` will match any path that has three segments, the first
of which is `foo`, the last `baz` and the middle segment can be anything
that starts with `b`. So, it would match:
* `cue "/foo/bar/baz"`
* `cue "/foo/baz/baz"`
* `cue "/foo/beans/baz"`
However, it wouldn't match the following:
* `cue "/foo/flibble/baz"`
* `cue "/foo/abaz/baz"`
* `cue "/foo/beans/baz/eggs"`
You can also place the `*` at the start of the segment to specify the
last characters of a segment: `"/foo/*zz/baz"` which will match any 3
segment `cue` or `set` where the first segment is `foo`, the last is
`baz` and the middle segment ends with `zz` such as `"cue
"/foo/whizz/baz"`.
## Matching Nested Path Segments
Sometimes you don't know how many path segments you want to match. In
these cases you can use the powerful double star: `**` such as
`"/foo/**/baz"` which will match:
* `cue "/foo/bar/baz"`
* `cue "/foo/bar/beans/baz"`
* `cue "/foo/baz"`
* `cue "/foo/a/b/c/d/e/f/baz"`
## Matching Single Letters
You can use the `?` character to match against a single char such as `"/?oo/bar/baz"` which will match:
* `cue "/foo/bar/baz"`
* `cue "/goo/bar/baz"`
* `cue "/too/bar/baz"`
* `cue "/woo/bar/baz"`
## Matching Multiple Words
If you know that a segment may be one of a select number of words, you
can use the `{` and `}` matchers to specify a list of choices such as
`"/foo/{bar,beans,eggs}/quux"` which will only match the following:
* `cue "/foo/bar/quux"`
* `cue "/foo/beans/quux"`
* `cue "/foo/eggs/quux"`
## Matching Multiple Letters
Finally, you can match against a selection of letters if you use the
`[` and `]` matchers to specify a list of choices such as
`"/foo/[abc]ux/baz"` which will match only:
* `cue "/foo/aux/baz"`
* `cue "/foo/bux/baz"`
* `cue "/foo/cux/baz"`
You can also use the `-` character to specify ranges of letters. For example `"/foo/[a-e]ux/baz"` which will match only:
* `cue "/foo/aux/baz"`
* `cue "/foo/bux/baz"`
* `cue "/foo/cux/baz"`
* `cue "/foo/dux/baz"`
* `cue "/foo/eux/baz"`
## Combining Matchers
When calling `sync` or `get` you are free to combine matchers in any
order you see fit to powerfully match any Time State event created by
`cue` or `set`. Let's look at a crazy example:
```
in_thread do
sync "/?oo/[a-z]*/**/ba*/{quux,quaax}/"
sample :loop_amen
end
sleep 1
cue "/foo/beans/a/b/c/d/e/bark/quux/"
```
## OSC Pattern Matching
For those curious, these matching rules are based on the Open Sound
Control pattern matching specification which is explained in detail
here: http://opensoundcontrol.org/spec-1_0
|