Search code examples
objective-cregexparsingcoding-styleregexkit

Best Practice: Partial Regex Matching


I'm not sure that regexes are the best solution here, but they seem logical enough; I'm just not sure how to actually implement this.

Basically, I want my user to be able to type in a method name and have it parsed for validity after each character input. I have defined a valid function format as a regex, and it is easy enough to test if the two match. The trouble is, I would like to be able to do a partial match, so as to let the user know, "So far, this is valid".

For example,

+(NSString *)thisIsAValid:(ObjectiveC *)method;

is a valid method. It can be matched by a simple regex string like

[\+-]\(w+\s*\*?\)\w+....etc...

. But I would love to be able to have that same regex string "match"

+(NSStr

(which I realize is sort of a backwards way of using regex). I would still not want the regex to match

Q)(NStr

Is there a way to implement something like this with standard regex functions, or would I have to do something more drastic?

Thanks so much! You guys are invaluable.


After further thinking, I suppose I could make my question a bit more clear (as well as a bit more succinct): Normally, one uses a regex to look for a pattern in text. I.e., how many times does "cat" or "cot" appear in this paragraph. I wish to do the opposite, look for a string "in" a regex. That is, how much of this string, starting from the beginning matches this regex. Ultimately, I would like to return the index at which the string ceases to match the regex in question.


Solution

  • RegexKit seams to use PCRE so you could try to use PCRE directly as it has support for partial matches.

    #include <stdio.h>
    #include <pcre.h>
    
    void test_match(pcre *re, char *subject);
    
    void test_match(pcre *re, char *subject) {
      int rc = pcre_exec(re, NULL, subject, (int)strlen(subject),
                         0, PCRE_PARTIAL, NULL, 0);
      printf("%s: %s\n", subject,
             rc == 0 || rc == PCRE_ERROR_PARTIAL ?
             "match or partial" : "no match");
    }
    
    int main (int argc, const char * argv[]) {
      pcre *re;
      const char *errstr;
      int erroffset;
    
      re = pcre_compile("^ABC$", 0, &errstr, &erroffset, NULL);
      test_match(re, "A");
      test_match(re, "AB");
      test_match(re, "ABC");
      test_match(re, "ABD");
    
      return 0;
    }
    

    Will print:

    A: match or partial
    AB: match or partial
    ABC: match or partial
    ABD: no match