Replace characters in NSString

13,894

Solution 1

NSError *error;

NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@"\\d" options:NSRegularExpressionCaseInsensitive error:&error];

NSString *newString = [regex stringByReplacingMatchesInString:string options:0 range:NSMakeRange(0, [string length]) withTemplate:@"*"];

Solution 2

I'm not sure why the accepted answer was accepted, since it only works if everything but last 4 is a digit. Here's a simple way:

NSMutableString * str1 = [[NSMutableString alloc]initWithString:@"1234567890ABCD"];
NSRange r = NSMakeRange(0, [str1 length] - 4);
[str1 replaceCharactersInRange:r withString:[[NSString string] stringByPaddingToLength:r.length withString:@"*" startingAtIndex:0]];
NSLog(@"%@",str1);

Solution 3

The most unintuitive part in Cocoa is creating the repeating stars without some kind of awkward looping. stringByPaddingToLength:withString:startingAtIndex: allows you to create a repeating string of any length you like, so once you have that, here's a simple solution:

NSInteger starUpTo = [string length] - 4;
if (starUpTo > 0) {
    NSString *stars = [@"" stringByPaddingToLength:starUpTo withString:@"*" startingAtIndex:0];
    return [string stringByReplacingCharactersInRange:NSMakeRange(0, starUpTo) withString:stars];
} else {
    return string;
}
Share:
13,894
ARC
Author by

ARC

Updated on July 19, 2022

Comments

  • ARC
    ARC almost 2 years

    I am trying to replace all characters except last 4 in a String with *'s.
    In objective-c there is a method in NSString class replaceStringWithCharactersInRange: withString: where I would give it range (0,[string length]-4) ) with string @"*". This is what it does: 123456789ABCD is modified to *ABCD while I am looking to make ********ABCD. I understand that it replaced range I specified with string object. How to accomplish this ?

  • ARC
    ARC over 12 years
    Did you actually read my question or copied answer from my question ? downvoted by me
  • Patrick Perini
    Patrick Perini over 12 years
    Try @"\d+" as your regularExpressionWithPattern: argument. I tried \\d+ on this regex tester, and it failed, but \d+ worked.
  • Lefteris
    Lefteris over 12 years
    Fixed it. Just replace \\d+ with \\d in the pattern. Just remember that regular expressions require iOS 4 or later. If you need it to work in iOS 3, you should us NSScanner
  • Vitaliy
    Vitaliy over 12 years
    NSMutableString * str1 = [[NSMutableString alloc]initWithString:@"1234567890ABCD"]; NSRange replacementRange = NSMakeRange(0, [str1 length] - 4); NSMutableString * replacementString = [[NSMutableString alloc]init]; for (uint i = 0; i < replacementRange.length; i++) { [replacementString appendString:@"*"]; } [str1 replaceCharactersInRange:replacementRange withString:replacementString]; NSLog(@"%@",str1);
  • Chuck
    Chuck over 12 years
    The problem with the original is that \d+ will greedily match every digit that it can, so they all become one match. Without the +, it matches individual digits, and thus replaces each one.
  • James Boutcher
    James Boutcher about 8 years
    Your solution addresses his exact input (1-9, then ABCD), but it doesn't answer the question does it? Replace all characters in "a" NSString, not that specific NSString.. How is this an answer?
  • Lefteris
    Lefteris about 8 years
    @JamesBoutcher Because the question is asking this. A question is not just the title.
  • James Boutcher
    James Boutcher about 8 years
    @Lefteris - What about the first sentence in the question?
  • James Boutcher
    James Boutcher about 8 years
    All this does it return a string that's *'d out. How does this answer the question? (Leaving the last 4?)
  • James Boutcher
    James Boutcher about 8 years
    replaceCharactersInRange doesn't repeat the string -- it just replaces it. So you're taking all but the last 4 characters and replacing them with a single character of *, reducing the length of the string.
  • Lefteris
    Lefteris about 8 years
    @JamesBoutcher A programmer should know how to modify an answer and adjust to his needs. You can change both the regular expression and the range in the NSMakeRange to adjust to your needs. SO is for giving you guidelines, not to provide copy/paste code, which might end up being voodoo code, where you use it without knowing how it does work and why, which is the worst thing to do.
  • CocoaChris
    CocoaChris over 7 years
    Hmm indeed, didn't read well enough. for (int i=0; i<[pass length] - 4; i++) { [secret appendString:@"*"]; } then use nsmakerange to copy the last 4 characters. But a better answer is already there