Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

raison

macrumors member
Original poster
Nov 13, 2009
83
4
I'm trying to grab everything after # on a string, so for this string:

A B C #123 456

I want to get 123 456.

I have "line" defined as String, and then I issue this:

Code:
let cmtRange: Range = line.rangeOfString("#")!

What should I do next? I can't understand the documentation very well, quite confusing. It has that rangeOfString returns NSRange, but in reality, it returns Range.

This doesn't work:
Code:
if(cmtRange.startIndex != NSNotFound) { ... }

This is the documentation I'm looking at, am I looking at the wrong place?
 
I played with this a little. I had to remove the exclamation mark to work with the result due to the possibility that the string does not contain the # character. Also, I believe that for Swift Apple has removed the use of NSNotFound.

Anyhow, I've demonstrated two ways to work the return value. The first by using the 'if let' syntax and the second using your method of first assigning to a variable for further use.

Code:
var line = "ABC # 123 456"


if let cmtRange1 = line.rangeOfString("#") {
    print("cmtRange1: \(cmtRange1)")
}
else {
    print("cmtRange1 is nil")
}


let cmtRange2 = line.rangeOfString("#")
if cmtRange2 != nil {
    print("cmtRange2: \(cmtRange2)")
}
else {
    print("cmtRange2 is nil")
}

if cmtRange2 != nil {
    let remainderStr = line.substringFromIndex(cmtRange2!.endIndex)
    let trimmedStr = remainderStr.stringByTrimmingCharactersInSet(NSCharacterSet.whitespaceAndNewlineCharacterSet())
    print("right Str: >\(remainderStr)<")
    print("trmd Str: >\(trimmedStr)<")
}
 
Swift is not stable yet.

One of the recent changes was removing the "NS" from various types - NS stands for NextStep, and if you know what NextStep is, then you are not a software developer but a software historian.

In Objective-C, the method _always_ returns an NSRange, and if the string isn't found, then startIndex == NSNotFound. In Swift, the same method returns an optional range - either nil, or a valid range. The ! means: "Please crash if the string isn't found". So in Swift you don't compare with NSNotFound; it will never be equal to NSNotFound, but


Code:
if let range = line.rangeOfString ("#") {
        // range is the range where the # was found
    } else {
        // rangeOfString returned nil.
        // There is no # in the string
    }
 
Last edited by a moderator:
Thank you so much for both of you. @xStep I will try your code soon, thanks for your time for putting it together! I see that you defined 2 ranges, cmtRange1 and cmtRange2. I assume this was for demonstration purpose, right? I can use cmtRange1 to retrieve what I want, it seems like. Anyway, I'll give it a try in a bit and let you know, thanks a lot!

@gnasher729 Thank you for the info. I'm relying on the XCode and developer.apple.com documentation sets, is there an updated documentation somewhere? I understand what you said, but I can't find in the documentation what you mentioned, such as returning Range instead of NSRange, and returning nil instead of NSNotFound. Did you get that from your experience with coding on Swift, or is it documented somewhere?

EDIT: I tested and worked like a charm, thanks @xStep. I also reread your comments and understood the reason for the 2 versions.
 
Last edited:
It looks like the duality of NSString and String adds to the confusion.

Code:
let abc : NSString = "Objective-C"
let xyz = abc.rangeOfString("-") // <- This returns an NSRange because abc is a NSString
if xyz.location == NSNotFound { // <- Now we can test against NSNotFound
    print("xyz.location is NSNotFound")
}
else {
    print("xyz: \(xyz)")
}
[SIZE=13px][\CODE][/SIZE]
 
NSRange and NSNotFound are not dead: they're just not recommended. If you really need NSRange for whatever reason, you can cast String to NSString:
Code:
var aRange = ("Hi" as NSString).rangeOfString("H") //returns an NSRange

This isn't reccommended, as converting to NSStrings take some time, and it'll begin adding up.

That said, there are times you'll need to use NSString's range, as String and NSString count characters differently, and some Objective-C/Cocoa functions expect NSRanges
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.