0

I would like to programmatically receive a JIRA ticket number, like @"ART-235", and obtain the bare digits / number, @"235".

A question I asked about using regular expressions turned up Regular expressions in an Objective-C Cocoa application with a link to https://developer.apple.com/library/ios/documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html, and it looks indeed like I can have a regular expression such as \D*?(\d+) and retrieve the value via a regular expression.

However, I wanted to check in and ask if there is a less bletcherous way to do this, or is this an example of why Objective-C is called a bit archaic? The second link gives what looks like everything I need, but it smells a little funny. For the objective stated above, do I want to use regular expressions, or is there a more nicely idiomatic way to perform this sort of string manipulation?

Community
  • 1
  • 1
Christos Hayward
  • 5,777
  • 17
  • 58
  • 113
  • Have you tried this: http://stackoverflow.com/questions/11711196/how-to-extract-split-numbers-and-string-out-from-nsstring – Gaurav Singh Sep 22 '13 at 19:32

4 Answers4

3

Sounds like -componentsSeparatedByString: would do what you need.

Catfish_Man
  • 41,261
  • 11
  • 67
  • 84
3

Getting pieces of a fixed, known, format that doesn't use paired delimiters or nesting is exactly the kind of thing that regexes are made to do. I don't see a thing wrong with using one here.

To address your question as written (about "iteration"), however, you might want to look at NSScanner, which does move through the characters of a string by "character class", allowing you to evaluate them as you go.

NSString * ticket = @"ART-235";

NSScanner * scanner = [NSScanner scannerWithString:ticket];
[scanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet]
                        intoString:nil];

// As an integer
NSInteger ticketNumber;
[scanner scanInteger:&ticketNumber];

// Or as a string
NSString * ticketNumber;
[scanner scanCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] 
                    intoString:&ticketNumber];
jscs
  • 63,694
  • 13
  • 151
  • 195
2

Like other answers have already said: that simple case can be solved using componentsSeparatedByString:@"-".

That said, your original question is how to enumerate individual characters.

Not all characters are of the same size, some languages combine more than one character into a new language. When enumerating such a string you most likely want to get the resulting of that composition, not the individual pieces. In Objective-C you can enumerate these composed characters like this:

NSString *myString = @"Hello Strings!";
[myString enumerateSubstringsInRange:NSMakeRange(0, myString.length)
                             options:NSStringEnumerationByComposedCharacterSequences
                          usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
                                  // Do something with the composed character 
                                  NSLog(@"%@", substring);
                              }];

The example above will log each character one by one.

David Rönnqvist
  • 56,267
  • 18
  • 167
  • 205
0

I made a simple method for you that does the trick, provided that the ticket identifiers will always be in a "string-number" format !

-(int) numberFromJiraTicket:(NSString*)ticketId
{
    //Get number as string
    NSString *number = [[ticketId componentsSeparatedByString:@"-"] lastObject];

    //Return the INT representation of the number
    return [number intValue];
}
Mostafa Berg
  • 3,211
  • 22
  • 36
  • 3
    why the cast in the return statement? – vikingosegundo Sep 22 '13 at 19:40
  • 1
    Why not `NSInteger` and `[number integerValue]`? – David Rönnqvist Sep 22 '13 at 19:42
  • Well it doesn't really do anything, I thought of putting it there to make it an emphasis that the return will be an int, that's all – Mostafa Berg Sep 22 '13 at 19:43
  • do u also use comments like `i++; // iterate i by one`? – vikingosegundo Sep 22 '13 at 19:44
  • @DavidRönnqvist well since OP didn't really specify, I preferred to give the simplest data type, so anyone coming from any language or Objc beginners won't get confused. – Mostafa Berg Sep 22 '13 at 19:45
  • @vikingosegundo very constructive today aren't ya buddy ? :D – Mostafa Berg Sep 22 '13 at 19:46
  • 2
    I am serious: You put extra clutter, saying you want to make things easier to get. I just want to show you that you achieve the opposite. – vikingosegundo Sep 22 '13 at 19:49
  • @vikingosegundo I disagree, yes, code that needs too many comments is considered "code smells", but this isn't the case, I'm just explaining to OP what each line does, even if it's evident what it does to me, you and OP, some new learner might stumble upon this later and gets it faster form comments.. this is about explaining how things work, and I think two lines of comments aren't "clutter".. – Mostafa Berg Sep 22 '13 at 19:53
  • if I add a cast `(int)` to a method returning a value called `intValue` and documented for returning a value of type `int` that is clutter for sure. if a newbie cant understand that such a intValue method will return an int, he will also do not know what casting is or an int for sure. – vikingosegundo Sep 22 '13 at 20:32
  • @vikingosegundo, Well that one makes yeah, I'll edit it out of the answer ! thanks – Mostafa Berg Sep 22 '13 at 21:44