/NSString_RegEx.m

http://github.com/laullon/gitx · Objective C · 97 lines · 65 code · 16 blank · 16 comment · 20 complexity · ba9003c7646c235a341f3718fde105d8 MD5 · raw file

  1. //
  2. // NSString_RegEx.m
  3. //
  4. // Created by John R Chang on 2005-11-08.
  5. // This code is Creative Commons Public Domain. You may use it for any purpose whatsoever.
  6. // http://creativecommons.org/licenses/publicdomain/
  7. //
  8. #import "NSString_RegEx.h"
  9. #include <regex.h>
  10. @implementation NSString (RegEx)
  11. - (NSArray *) substringsMatchingRegularExpression:(NSString *)pattern count:(int)nmatch options:(int)options ranges:(NSArray **)ranges error:(NSError **)error
  12. {
  13. options |= REG_EXTENDED;
  14. if (error)
  15. *error = nil;
  16. int errcode = 0;
  17. regex_t preg;
  18. regmatch_t * pmatch = NULL;
  19. NSMutableArray * outMatches = nil;
  20. // Compile the regular expression
  21. errcode = regcomp(&preg, [pattern UTF8String], options);
  22. if (errcode != 0)
  23. goto catch_error; // regcomp error
  24. // Match the regular expression against substring self
  25. pmatch = calloc(sizeof(regmatch_t), nmatch+1);
  26. errcode = regexec(&preg, [self UTF8String], (nmatch<0 ? 0 : nmatch+1), pmatch, 0);
  27. /*if (errcode == REG_NOMATCH)
  28. {
  29. outMatches = [NSMutableArray array];
  30. goto catch_exit; // no match
  31. }*/
  32. if (errcode != 0)
  33. goto catch_error; // regexec error
  34. if (nmatch == -1)
  35. {
  36. outMatches = [NSArray arrayWithObject:self];
  37. goto catch_exit; // simple match
  38. }
  39. // Iterate through pmatch
  40. outMatches = [NSMutableArray array];
  41. if (ranges)
  42. *ranges = [NSMutableArray array];
  43. int i;
  44. for (i=0; i<nmatch+1; i++)
  45. {
  46. if (pmatch[i].rm_so == -1 || pmatch[i].rm_eo == -1)
  47. break;
  48. NSRange range = NSMakeRange(pmatch[i].rm_so, pmatch[i].rm_eo - pmatch[i].rm_so);
  49. NSString * substring = [[NSString alloc] initWithBytes:[self UTF8String] + range.location
  50. length:range.length
  51. encoding:NSUTF8StringEncoding];
  52. [outMatches addObject:substring];
  53. if (ranges)
  54. {
  55. NSValue * value = [NSValue valueWithRange:range];
  56. [(NSMutableArray *)*ranges addObject:value];
  57. }
  58. }
  59. catch_error:
  60. if (errcode != 0 && error)
  61. {
  62. // Construct error object
  63. NSMutableDictionary * userInfo = [NSMutableDictionary dictionary];
  64. char errbuf[256];
  65. int len = regerror(errcode, &preg, errbuf, sizeof(errbuf));
  66. if (len > 0)
  67. [userInfo setObject:[NSString stringWithUTF8String:errbuf] forKey:NSLocalizedDescriptionKey];
  68. *error = [NSError errorWithDomain:@"regerror" code:errcode userInfo:userInfo];
  69. }
  70. catch_exit:
  71. if (pmatch)
  72. free(pmatch);
  73. regfree(&preg);
  74. return outMatches;
  75. }
  76. - (BOOL) grep:(NSString *)pattern options:(int)options
  77. {
  78. NSArray * substrings = [self substringsMatchingRegularExpression:pattern count:-1 options:options ranges:NULL error:NULL];
  79. return (substrings && [substrings count] > 0);
  80. }
  81. @end