Perhaps it makes sense to introduce a level of abstraction here; Rather than recording a list of pattern, we could include a list of  "abstractions", each of which would know how to "compile" and "compare". That way, you'd reduce the checking for "^" down to one spot only and during the loop, you'd invoke the abstraction to figure out the boolean match.