20

这会从字符串的两端删除空格:

NSString *newString = [oldString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];

如何从字符串的右端删除空格?

更新:接受答案的代码现在是SSToolkit的一部分。耶!

4

4 回答 4

32

更新:一个快速的基准测试表明,基于Max' & mine的 Matt 自己的改编表现最好。

@implementation NSString (TrimmingAdditions)

- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
    NSUInteger location = 0;
    NSUInteger length = [self length];
    unichar charBuffer[length];    
    [self getCharacters:charBuffer];

    for (location; location < length; location++) {
        if (![characterSet characterIsMember:charBuffer[location]]) {
            break;
        }
    }

    return [self substringWithRange:NSMakeRange(location, length - location)];
}

- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
    NSUInteger location = 0;
    NSUInteger length = [self length];
    unichar charBuffer[length];    
    [self getCharacters:charBuffer];

    for (length; length > 0; length--) {
        if (![characterSet characterIsMember:charBuffer[length - 1]]) {
            break;
        }
    }

    return [self substringWithRange:NSMakeRange(location, length - location)];
}

@end

进而:

NSString *trimmedString = [yourString stringByTrimmingTrailingCharactersInSet:[NSCharacterset whitespaceAndNewlineCharacterSet]];

或用于前导空格:

NSString *trimmedString = [yourString stringByTrimmingLeadingCharactersInSet:[NSCharacterset whitespaceAndNewlineCharacterSet]];

它以抽象的方式实现,因此您可以在任何可能的情况下使用它NSCharacterSetwhitespaceAndNewlineCharacterSet只是其中之一。

为方便起见,您可能需要添加这些包装器方法:

- (NSString *)stringByTrimmingLeadingWhitespace {
    return [self stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

- (NSString *)stringByTrimmingTrailingWhitespace {
    return [self stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
}

- (NSString *)stringByTrimmingLeadingWhitespaceAndNewline {
    return [self stringByTrimmingLeadingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)stringByTrimmingTrailingWhitespaceAndNewline {
    return [self stringByTrimmingTrailingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

编辑:使用 charBuffer 恢复到初始版本以获得更好的性能。

于 2011-04-16T20:14:41.450 回答
18

基于@Regexident 和@Max 的答案,我想出了以下方法:

@implementation NSString (SSToolkitAdditions)

#pragma mark Trimming Methods

- (NSString *)stringByTrimmingLeadingCharactersInSet:(NSCharacterSet *)characterSet {
    NSRange rangeOfFirstWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]];
    if (rangeOfFirstWantedCharacter.location == NSNotFound) {
        return @"";
    }
    return [self substringFromIndex:rangeOfFirstWantedCharacter.location];
}

- (NSString *)stringByTrimmingLeadingWhitespaceAndNewlineCharacters {
    return [self stringByTrimmingLeadingCharactersInSet:
            [NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
    NSRange rangeOfLastWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]
                                                               options:NSBackwardsSearch];
    if (rangeOfLastWantedCharacter.location == NSNotFound) {
        return @"";
    }
    return [self substringToIndex:rangeOfLastWantedCharacter.location+1]; // non-inclusive
}

- (NSString *)stringByTrimmingTrailingWhitespaceAndNewlineCharacters {
    return [self stringByTrimmingTrailingCharactersInSet:
            [NSCharacterSet whitespaceAndNewlineCharacterSet]];
}

@end

这里是 GHUnit 测试,当然都通过了:

@interface StringCategoryTest : GHTestCase
@end

@implementation StringCategoryTest

- (void)testStringByTrimmingLeadingCharactersInSet {
    NSCharacterSet *letterCharSet = [NSCharacterSet letterCharacterSet];
    GHAssertEqualObjects([@"zip90210zip" stringByTrimmingLeadingCharactersInSet:letterCharSet], @"90210zip", nil);
}

- (void)testStringByTrimmingLeadingWhitespaceAndNewlineCharacters {
    GHAssertEqualObjects([@"" stringByTrimmingLeadingWhitespaceAndNewlineCharacters], @"", nil);
    GHAssertEqualObjects([@"\n \n " stringByTrimmingLeadingWhitespaceAndNewlineCharacters], @"", nil);
    GHAssertEqualObjects([@"\n hello \n" stringByTrimmingLeadingWhitespaceAndNewlineCharacters], @"hello \n", nil);
}

- (void)testStringByTrimmingTrailingCharactersInSet {
    NSCharacterSet *letterCharSet = [NSCharacterSet letterCharacterSet];
    GHAssertEqualObjects([@"zip90210zip" stringByTrimmingTrailingCharactersInSet:letterCharSet], @"zip90210", nil);
}

- (void)testStringByTrimmingTrailingWhitespaceAndNewlineCharacters {
    GHAssertEqualObjects([@"" stringByTrimmingLeadingWhitespaceAndNewlineCharacters], @"", nil);
    GHAssertEqualObjects([@"\n \n " stringByTrimmingLeadingWhitespaceAndNewlineCharacters], @"", nil);
    GHAssertEqualObjects([@"\n hello \n" stringByTrimmingTrailingWhitespaceAndNewlineCharacters], @"\n hello", nil);
}

@end

我向SSToolkit提交了一个 GitHub 拉取请求,并添加了这些方法。

于 2011-04-17T04:53:30.250 回答
7
NSString* str = @"hdskfh   dsakjfh akhf kasdhfk asdfkjash fkadshf1234        ";
NSRange rng = [str rangeOfCharacterFromSet: [NSCharacterSet characterSetWithCharactersInString: [str stringByReplacingOccurrencesOfString: @" " withString: @""]] options: NSBackwardsSearch];
str = [str substringToIndex: rng.location+1];
于 2011-04-16T21:44:59.347 回答
1

当最后一个非尾随字符是多字节时,需要稍作更改以说明情况:

- (NSString *)stringByTrimmingTrailingCharactersInSet:(NSCharacterSet *)characterSet {
    NSRange rangeOfLastWantedCharacter = [self rangeOfCharacterFromSet:[characterSet invertedSet]
                                                               options:NSBackwardsSearch];
    if (rangeOfLastWantedCharacter.location == NSNotFound) {
        return @"";
    }
    return [self substringToIndex:rangeOfLastWantedCharacter.location + rangeOfLastWantedCharacter.length]; // non-inclusive
}
于 2012-06-21T00:09:54.540 回答