Code Monkey home page Code Monkey logo

objective-c-regex-categories's Introduction

Objective-C RegEx Categories

Table of Contents

Make Regular Expressions Easier in Objective-C

## Introduction

This project makes regular expressions easy in Objective-C.

As of iOS 4 (and OSX 10.7), NSRegularExpression is built-in to Foundation.framework. The syntax is somewhat cumbersome and it leaves much of the work to you, so this library creates categories and macros to simplify usage of NSRegularExpression.

Here is an example where four lines of code become one:

// Without this library
NSString* string = @"I have 2 dogs.";
NSRegularExpression *regex = [NSRegularExpression regular ExpressionWithPattern:@"\\d+" options:NSRegularExpressionCaseInsensitive error:&error];
NSTextCheckingResult *match = [regex firstMatchInString:string options:0 range:NSMakeRange(0, [string length])];
BOOL isMatch = match != nil;

// With this library
BOOL isMatch = [@"I have 2 dogs." isMatch:RX(@"\\d+")];

TIP: Refer to the header (RegExCategories.h) for more details and examples.

## Getting Started

This library has no dependencies and works for iOS 4+ and OSX 10.7+.

To install it, just copy these two files into your project:

You may want to add it to your AppName-Prefix.pch so that is is available across your code base.

#ifdef __OBJC__
    /* ...other references... */
    #import "RegExCategories.h"
#endif

You also need to have ARC enabled on your XCode project. If you don't then add the -fobjc-arc flag on RegExCategories.m under Targets > Build Phases > Compile Sources (more info).

## Quick Examples

Here are some short examples of how you might use the code. The documentation section below goes into full detail.

//Create an NSRegularExpression
Rx* rx = RX(@"\\d");
Rx* rx = [Rx rx:@"\\d"];
Rx* rx = [Rx rx:@"\\d" ignoreCase:YES];

//Test if a string matches
BOOL isMatch = [@"2345" isMatch:RX(@"^\\d+$")];

//Get first match
NSString* age = [@"My dog is 3." firstMatch:RX(@"\\d+")];

//Get matches as a string array
NSArray* words = [@"Hey pal" matches:RX(@"\\w+")];
// words => @[ @"Hey", @"pal" ]

//Get first match with details
RxMatch* match = [@"12.34, 56.78" firstMatchWithDetails:RX(@"\\d+([.]\\d+)")];
// match.value => @"12.34"
// match.range => NSRangeMake(0, 5);
// match.original => @"12.34, 56.78";
// match.groups => @[ RxMatchGroup, RxMatchGroup ];

//Replace with a template string
NSString* result = [@"My dog is 12." replace:RX(@"\\d+") with:@"old"];
// result => @"My dog is old."

//Replace with a block
NSString* result = [RX(@"\\w+") replace:@"hi bud" withBlock:^(NSString* match){
  return [NSString stringWithFormat:@"%i", match.length];
}];
// result => @"2 3"

//Replace with a block that has the match details
NSString* result = [RX(@"\\w+") replace:@"hi bud" withDetailsBlock:^(RxMatch* match){
  return [NSString stringWithFormat:@"%i", match.value.length];
}];
// result => @"2 3"
## Documentation ## Macros

First off, we create an alias for NSRegularExpression named Rx. So instead of writing NSRegularExpression you can now use Rx. (this can be disabled - read on)

//this
NSRegularExpression* rx = [[NSRegularExpression alloc] initWithPattern:@"\\d"];

//can be written as
Rx* rx = [[Rx alloc] initWithPattern:@"\\d"];

We've also created a macro RX() for quick regex creation. Just pass a string and an NSRegularExpression object is created:

//this
NSRegularExpression* rx = [[NSRegularExpression alloc] initWithPattern:@"\\d"];

//can be written as
Rx* rx = RX(@"\\d");

These macros can be disabled by defining DisableRegExCategoriesMacros before you include the script. For example:

#define DisableRegExCategoriesMacros
#include "RegExCategories.h"
## Creation

Here are a few convenient ways to create an NSRegularExpression.

######Class Method - rx

Rx* rx = [Rx rx:@"\\d+"];

######Class Method - ignore case

Rx* rx = [Rx rx:@"\\d+" ignoreCase:YES];

######Class Method - with options

Rx* rx = [Rx rx:@"\\d+" options:NSRegularExpressionCaseInsensitive];

######Init With Pattern

Rx* rx = [[Rx alloc] initWithPattern:@"\d+"];

######String Extension

Rx* rx = [@"\\d+" toRx];

######String Extension - ignore case

Rx* rx = [@"\\d+" toRxIgnoreCase:YES];

######String Extension - with options

Rx* rx = [@"\\d+" toRxWithOptions:NSRegularExpressionCaseInsensitive];
##Test If Match

Tests whether a regular expression matches a string.

######From NSRegularExpression

BOOL isMatch = [RX(@"\\d+") isMatch:@"Dog #1"];
// => true

######From NSString

BOOL isMatch = [@"Dog #1" isMatch:RX(@"\\d+")];
// => true
##Index Of Match

Get the character index of the first match. If no match is found, then -1.

######From NSRegularExpression

int index = [RX(@"\\d+") indexOf:@"Buy 1 dog or buy 2?"];
// => 4

int index = [RX(@"\\d+") indexOf:@"Buy a dog?"];
// => -1

######From NSString

int index = [@"Buy 1 dog or buy 2?" indexOf:RX(@"\\d+")];
// => 4

int index = [@"Buy a dog?" indexOf:RX(@"\\d+")];
// => -1
##Split A String

Split an NSString using a regex as the delimiter. The result is an NSArray of NSString objects.

######From NSRegularExpression

NSArray* pieces = [RX(@"[ ,]") split:@"A dog,cat"];
// => @[@"A", @"dog", @"cat"]

######From NSString

NSArray* pieces = [@"A dog,cat" split:RX(@"[ ,]")];
// => @[@"A", @"dog", @"cat"]

Empty results are not removed. For example:

NSArray* pieces = [@",a,,b," split:RX(@"[,]")];
// => @[@"", @"a", @"", @"b", @""]
##First Match

Get the first match as an NSString. If no match is found, nil is returned.

NSString* match = [@"55 or 99 spiders" firstMatch:RX(@"\\d+")];
// => @"55"

NSString* match = [@"A lot of spiders" firstMatch:RX(@"\\d+")];
// => nil
First Match from NSRegularExpression
NSString* match = [RX(@"\\d+") firstMatch:@"55 or 99 spiders"];
// => @"55"
First Match With Details (from NSString or NSRegularExpression)

If you want more details about the match (such as the range or captured groups), then use match with details. It returns an RxMatch object if a match is found, otherwise nil.

RxMatch* match = [@"55 or 99 spiders" firstMatchWithDetails:RX(@"\\d+")];
// => { value: @"55", range:NSRangeMake(0, 2), groups:[RxMatchGroup, ...] }

RxMatch* match = [@"A lot of spiders" firstMatchWithDetails:RX(@"\\d+")];
// => nil

RxMatch* match = [RX(@"\\d+") firstMatchWithDetails:@"55 or 99 spiders"];
// => { value: @"55", range:NSRangeMake(0, 2), groups:[RxMatchGroup, ...] }
##Matches

Matches returns all matches as an NSArray, each as an NSString. If no matches are found, the NSArray is empty.

NSArray* matches = [@"55 or 99 spiders" matches:RX(@"\\d+")];
// => @[ @"55", @"99" ]

NSArray* matches = [RX(@"\\d+") matches:@"55 or 99 spiders"];
// => @[ @"55", @"99" ]
Matches With Details (from NSString or NSRegularExpression)

Matches with details returns all matches as an NSArray, each object is an RxMatch object.

NSArray* matches = [@"55 or 99 spiders" matchesWithDetails:RX(@"\\d+")];
// => @[ RxMatch, RxMatch ]

NSArray* matches = [RX(@"\\d+") matchesWithDetails:@"55 or 99 spiders"];
// => @[ RxMatch, RxMatch ]
##Replace

Replace allows you to replace matched substrings with a templated string.

NSString* result = [RX(@"ruf+") replace:@"ruf ruff!" with:@"meow"];
// => @"meow meow!"
Replace With Block

Replace with block lets you pass an objective-c block that returns the replacement NSString. The block receives an NSString which is the matched substring.

NSString* result = [RX(@"[A-Z]+") replace:@"i love COW" withBlock:^(NSString*){ return @"lamp"; }];
// => @"i love lamp"
Replace With Details Block

Similar to replace with block, but this block receives an RxMatch for each match. This gives you details about the match such as captured groups.

NSString* result = [RX(@"\\w+") replace:@"two three" withDetailsBlock:^(RxMatch* match){ 
    return [NSString stringWithFormat:@"%i", match.value.length];
  }];
// => @"3 5"
Replace From NSString

Replace can also be called from an NSString.

NSString* result = [@"ruf ruff!" replaceRX(@"ruf+") with:@"meow"];
// => @"meow meow!"

NSString* result = [@"i love COW" replace:RX(@"[A-Z]+") withBlock:^(NSString*){ return @"lamp"; }];
// => @"i love lamp"

NSString* result = [@"two three" replace:RX(@"\\w+") withDetailsBlock:^(RxMatch* match){ 
    return [NSString stringWithFormat:@"%i", match.value.length];
}];
// => @"3 5"
## RxMatch Objects

RxMatch and RxMatchGroup are objects that contain information about a match and its groups.

@interface RxMatch : NSObject

	/* The substring that matched the expression. */
	@property (retain) NSString* value;    

	/* The range of the original string that was matched. */
	@property (assign) NSRange   range;    

	/* Each object is an RxMatchGroup. */
	@property (retain) NSArray*  groups;   

	/* The full original string that was matched against.  */
	@property (retain) NSString* original; 

@end

@interface RxMatchGroup : NSObject

   /* The substring matched for the group. */
	@property (retain) NSString* value;
	
   /* The range of the captured group, relative to the original string. */
	@property (assign) NSRange range;
		
@end
## Support

If you need help, submit an issue or send a pull request. Please include appropriate unit tests in any pull requests.

You can visit my website at joshwright.com or tweet at me @BendyTree.

## Licensing

MIT License - do whatever you want, just (1) provide attribution and (2) don't hold me liable.

## Testing

This repository includes unit tests written in the XCTest framework.

## Alternatives

There are a few other options for using regular expressions in objective-c including:

## Who Uses It?

Here is a list of projects using Objective-C RegEx Categories. If you're using it, tweet at me (@BendyTree) and I'll add you to the list:

objective-c-regex-categories's People

Contributors

bendytree avatar stigi avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.