How to remove whitespace from right end of NSString?

后端 未结 4 789
刺人心
刺人心 2020-11-29 09:01

This removes white space from both ends of a string:

NSString *newString = [oldString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCha         


        
相关标签:
4条回答
  • 2020-11-29 09:48
    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];
    
    0 讨论(0)
  • 2020-11-29 09:53

    UPDATE: A quick benchmark showed that Matt's own adaption, based on Max' & mine, performs best.

    @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
    

    and then:

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

    or for leading whitespace:

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

    It's implemented in an abstract fashion so you can use it with any possible NSCharacterSet, whitespaceAndNewlineCharacterSet being just one of them.

    For convenience you might want to add these wrapper methods:

    - (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]];
    }
    

    Edit: reverted back to initial version using charBuffer for better performance.

    0 讨论(0)
  • 2020-11-29 10:05

    Building on the answers by @Regexident & @Max, I came up with the following methods:

    @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
    

    And here are the GHUnit tests, which all pass of course:

    @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
    

    I submitted a GitHub pull request to SSToolkit with these methods added.

    0 讨论(0)
  • 2020-11-29 10:06

    Needs a slight change to account for the case when last non-trailing character is multibyte:

    - (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
    }
    
    0 讨论(0)
提交回复
热议问题