Search code examples
swiftnsregularexpressionswift2nsrangeexception

Swift 2.0: NSRangeException, Range or index out of bounds


Context: I come from 15-20 years of JavaScript, Ruby and (modern) PHP. I've been poking at Swift over the last year, and I'm brand-new to Cocoa.

Here's a simplified test case that I'm running in Xcode 7.0 β2:

#! /usr/bin/env swift

import Foundation

// Extend the String object with helpers
extension String {

    // String.replace(); similar to JavaScript's String.replace() and Ruby's String.gsub()
    func replace(pattern: String, replacement: String) -> String {

        // Debugging
        print(self.characters.count)
        print(NSMakeRange(0, self.characters.count - 1))

        let regex = try! NSRegularExpression(
            pattern: pattern,
            options: [.CaseInsensitive]
        )

        return regex.stringByReplacingMatchesInString(
            replacement,
            options: [.Anchored],
            range: NSMakeRange(0, self.characters.count - 1),
            withTemplate: "xx"
        )
    }
}

let prefix = "abc     123".replace("\\s+", replacement: " ")

print(prefix)

The two debugging lines display:

11
(0,10)

After that, the app crashes with the following message:

2015-06-24 23:18:45.027 swift[42912:648900] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSRegularExpression enumerateMatchesInString:options:range:usingBlock:]: Range or index out of bounds'

I've looked over the following documentation, but nothing is jumping out to me:

I can only think that the issue has something to do with passing an NSRange instance as a parameter to the stringByReplacingMatchesInString() method, but I've tried adjusting the value to NSRange(0,1) and NSRange(1,2) expecting to see something that would help, but it's still throwing the exception.

As I wrote in the title, I'm working in Swift 2.0.


Solution

  • I see that the first argument to stringByReplacingMatchesInString is 'replacement'. Should this be 'self'?