itsZazzles
itsZazzles

Reputation: 43

Getting a empty Range<String.Index> in Swift

I am very new to Swift and have trying to use regular expressions, but getting the match from the string seems to be an insurmountable task.

This is my current approach.

print(data.substring(with: (data.range(of: "[a-zA-Z]at", options: .regularExpression))))

This doesn't work because

Value of optional type 'Range<String.Index>?' must be unwrapped to a value of type 'Range<String.Index>'

I guess this has something to do with it possibly being null, so now i want to provide it with an alternative using the ?? operator.

print(data.substring(with: (data.range(of: "[a-zA-Z]at", options: .regularExpression) ?? Range<String.Index>())))

What i want to do is to provide it with an empty range object but it seems to be impossible to create an empty object of the type required.

Any suggestions?

Upvotes: 2

Views: 968

Answers (3)

Chus
Chus

Reputation: 195

You can create such constructor with a simple extension to Range type. Like this:

extension Range where Bound == String.Index {
    static var empty: Range<Bound> {
        "".startIndex..<"".startIndex
    }

    init() {
        self = Range<Bound>.empty
    }
}

Then it can be used like this:

let str = "kukukukuku"
let substr1 = str[str.range(of: "abc", options: .regularExpression) ?? Range<String.Index>()]
let substr2 = str[str.range(of: "abc", options: .regularExpression) ?? Range<String.Index>.empty]

Upvotes: 0

David Pasztor
David Pasztor

Reputation: 54716

Instead of trying to create an empty range, I would suggest creating an empty Substring in case there was no match. Range can be quite error-prone, so using this approach you can save yourself a lot of headaches.

let match: Substring
if let range = data.range(of: "[a-zA-Z]at", options: .regularExpression) {
    match = data[range]
} else {
    match = ""
}
print(match)

Upvotes: 2

Sweeper
Sweeper

Reputation: 271660

There is simply no argument-less initialiser for Range<String.Index>.

One way you can create an empty range of String.Index is to use:

data.startIndex..<data.startIndex

Remember that you shouldn't use integers here, because we are dealing with indices of a string. See this if you don't understand why.

So:

print(data.substring(with: (data.range(of: "[a-zA-Z]at", options: .regularExpression) ?? data.startIndex..<data.startIndex)))

But substring(with:) is deprecated. You are recommended to use the subscript:

print(data[data.range(of: "[a-zA-Z]at", options: .regularExpression) ?? data.startIndex..<data.startIndex])

Upvotes: 3

Related Questions