commit 1da50d395da1ec5cadecbef6e011363cb1b2dba3 Author: Said Achmiz Date: Wed Apr 6 14:44:33 2016 -0400 First commit diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000..5008ddf Binary files /dev/null and b/.DS_Store differ diff --git a/NSString+SA_NSStringExtensions.h b/NSString+SA_NSStringExtensions.h new file mode 100644 index 0000000..7279b98 --- /dev/null +++ b/NSString+SA_NSStringExtensions.h @@ -0,0 +1,26 @@ +// +// NSString+SA_NSStringExtensions.h +// +// Copyright (c) 2016 Said Achmiz. +// +// This software is licensed under the MIT license. +// See the file "LICENSE" for more information. + +#import + +@interface NSString (SA_NSStringExtensions) + +- (BOOL)containsCharactersInSet:(NSCharacterSet *)characters; +- (BOOL)containsCharactersInString:(NSString *)characters; + +- (NSRange)firstWhitespaceAfterRange:(NSRange)aRange; +- (NSRange)firstNonWhitespaceAfterRange:(NSRange)aRange; + +- (NSRange)rangeAfterRange:(NSRange)aRange; +- (NSRange)rangeFromEndOfRange:(NSRange)aRange; +- (NSRange)rangeToEndFrom:(NSRange)aRange; + +- (NSArray *)componentsSplitByWhitespace; +- (NSArray *)componentsSplitByWhitespaceWithMaxSplits:(NSUInteger)maxSplits; + +@end diff --git a/NSString+SA_NSStringExtensions.m b/NSString+SA_NSStringExtensions.m new file mode 100644 index 0000000..3e332bf --- /dev/null +++ b/NSString+SA_NSStringExtensions.m @@ -0,0 +1,119 @@ +// +// NSString+SA_NSStringExtensions.m +// +// Copyright (c) 2016 Said Achmiz. +// +// This software is licensed under the MIT license. +// See the file "LICENSE" for more information. + +#import "NSString+SA_NSStringExtensions.h" + +#import "NSRange-Conventional.h" + +@implementation NSString (SA_NSStringExtensions) + +- (BOOL)containsCharactersInSet:(NSCharacterSet *)characters +{ + NSRange rangeOfCharacters = [self rangeOfCharacterFromSet:characters]; + return rangeOfCharacters.location != NSNotFound; +} + +- (BOOL)containsCharactersInString:(NSString *)characters +{ + return [self containsCharactersInSet:[NSCharacterSet characterSetWithCharactersInString:characters]]; +} + +- (NSRange)firstWhitespaceAfterRange:(NSRange)aRange +{ + NSRange restOfString = NSRangeMake(NSRangeMax(aRange), self.length - NSRangeMax(aRange)); + NSRange firstWhitespace = [self rangeOfCharacterFromSet:[NSCharacterSet whitespaceCharacterSet] options:0 range:restOfString]; + + return firstWhitespace; +} + +- (NSRange)firstNonWhitespaceAfterRange:(NSRange)aRange +{ + NSRange restOfString = NSRangeMake(NSRangeMax(aRange), self.length - NSRangeMax(aRange)); + NSRange firstNonWhitespace = [self rangeOfCharacterFromSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet] options:0 range:restOfString]; + + return firstNonWhitespace; +} + +- (NSRange)rangeAfterRange:(NSRange)aRange +{ + return NSRangeMake(NSRangeMax(aRange), self.length - NSRangeMax(aRange)); +} + +- (NSRange)rangeFromEndOfRange:(NSRange)aRange +{ + return NSRangeMake(NSRangeMax(aRange) - 1, self.length - NSRangeMax(aRange) + 1); +} + +- (NSRange)rangeToEndFrom:(NSRange)aRange +{ + return NSRangeMake(aRange.location, self.length - aRange.location); +} + +- (NSArray *)componentsSplitByWhitespace +{ + return [self componentsSplitByWhitespaceWithMaxSplits:NSUIntegerMax]; +} + +- (NSArray *)componentsSplitByWhitespaceWithMaxSplits:(NSUInteger)maxSplits +{ + if(maxSplits == 0) + { + return [NSMutableArray arrayWithObject:self]; + } + + __block NSMutableArray *components = [NSMutableArray array]; + + __block NSUInteger tokenStart; + __block NSUInteger tokenEnd; + __block BOOL currentlyInToken = NO; + __block NSRange tokenRange = NSRangeMake(NSNotFound, 0); + + __block NSUInteger splits = 0; + + [self enumerateSubstringsInRange:NSRangeMake(0, self.length) + options:NSStringEnumerationByComposedCharacterSequences + usingBlock:^(NSString *character, NSRange characterRange, NSRange enclosingRange, BOOL *stop) + { + if(currentlyInToken == NO && [character containsCharactersInSet:[[NSCharacterSet whitespaceCharacterSet] invertedSet]]) + { + currentlyInToken = YES; + tokenStart = characterRange.location; + } + else if(currentlyInToken == YES && [character containsCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]) + { + currentlyInToken = NO; + tokenEnd = characterRange.location; + + tokenRange = NSRangeMake(tokenStart, tokenEnd - tokenStart); + [components addObject:[self substringWithRange:tokenRange]]; + splits++; + if(splits == maxSplits) + { + *stop = YES; + NSRange lastTokenRange = [self rangeToEndFrom:[self firstNonWhitespaceAfterRange:tokenRange]]; + if(lastTokenRange.location != NSNotFound) + { + [components addObject:[self substringWithRange:lastTokenRange]]; + } + } + } + }]; + + // If we were in a token when we got to the end, add that last token. + if(splits < maxSplits && currentlyInToken == YES) + { + tokenEnd = self.length; + + tokenRange = NSRangeMake(tokenStart, tokenEnd - tokenStart); + [components addObject:[self substringWithRange:tokenRange]]; + } + + return components; +} + +@end