+/* Perl-Compatible RegEx {{{ */
+class Pcre {
+ private:
+ pcre *code_;
+ pcre_extra *study_;
+ int capture_;
+ int *matches_;
+ const char *data_;
+
+ public:
+ Pcre(const char *regex, int options = 0) :
+ study_(NULL)
+ {
+ const char *error;
+ int offset;
+ code_ = pcre_compile(regex, options, &error, &offset, NULL);
+
+ if (code_ == NULL)
+ @throw [NSException exceptionWithName:NSInvalidArgumentException reason:[NSString stringWithFormat:@"*** Pcre(,): [%u] %s", offset, error] userInfo:nil];
+
+ pcre_fullinfo(code_, study_, PCRE_INFO_CAPTURECOUNT, &capture_);
+ matches_ = new int[(capture_ + 1) * 3];
+ }
+
+ ~Pcre() {
+ pcre_free(code_);
+ delete matches_;
+ }
+
+ NSString *operator [](size_t match) {
+ return [[[NSString alloc] initWithBytes:(data_ + matches_[match * 2]) length:(matches_[match * 2 + 1] - matches_[match * 2]) encoding:NSUTF8StringEncoding] autorelease];
+ }
+
+ bool operator ()(NSString *data) {
+ // XXX: length is for characters, not for bytes
+ return operator ()([data UTF8String], [data length]);
+ }
+
+ bool operator ()(const char *data, size_t size) {
+ data_ = data;
+ return pcre_exec(code_, study_, data, size, 0, 0, matches_, (capture_ + 1) * 3) >= 0;
+ }
+};
+/* }}} */