Last week, I wrote about Olivier Halligon’s elegant
Set matching solution. Several people asked if this could be extended to pattern matching for other types, which it can. Today, I put together a little proof of concept for performing regular expression matching with strings.
I started off with the same struct plus stand-alone global pseudo-constructor approach I had used with sets. Doing so, let me have a
RegexPatternMatcher type and implement a
matching function to hide a constructor. After a bit of playing around, I dropped the global function to use a normal initializer:
matching("pattern"). The call sites were longer but less garbage floating around.
Renaming the type to
Regex provided a more succinct approach :
Regex("pattern"). I don’t normally like using overly short type names to balance call sites but I felt that
Regex said about all that needed to be spoken here:
I’m not a huge fan of
NSRegularExpression. I can’t wait for a native Swift solution. The class is expensive and it relies on what feels like archaic string models that use
NSRange. Olivier suggested I balance the expense with
NSCache so I created a variation where converted my struct to a class, and used
NSString patterns as the cache keys.
This allowed me to build each
NSRegularExpression instance once and decouple the matching
options from the pattern. I made the class
match function ignore defaulted option arguments. Instead, I allow the cache to carry forward any matching policies that previously existed or overwrite those policies if you specify them explicitly.
There’s something wrong with my code because I could not get a cached regex to change its matching behavior even after I updated options. Look at lines 103 through 107 in this version. If you figure out what’s wrong, let me know. It returns
true for all six tests, instead of four
true then two
Anyway, it was an interesting exercise and a good way to start getting back to work as I recuperate.