Search a string for barcodes but ignore certain characters
edit: The first time I read your code I mis-interpreted what was happening because of the signature of the function, and I suggested an approach that you were already using ¯_(ツ)_/¯ 

I like managing the loop using String.Index instead of Int because it saves a lot of casting you'd need to do otherwise (this is all in Swift 3).

let text = "hello"
var position = text.startIndex
while position &lt; text.endIndex {
    let character = text[position] // get substring at range
    print(character)
    position = text.index(after: position) // increment index by 1
}
// -&gt; prints
// h
// e
// l
// l
// o


Here's my approach that I hope gives you some inspiration or ideas!

edit: updated to loop over unicode scalars so it's easier to use exclusions.contains(currentCharacter)

extension String {

    func range(of target: String, ignoring exclusions: CharacterSet) -&gt; Range&lt;String.Index&gt;? {

        var startPosition = unicodeScalars.startIndex

        let limit = unicodeScalars.index(unicodeScalars.endIndex, offsetBy: -target.unicodeScalars.count)

        while startPosition &lt; limit {

            var targetPosition = target.unicodeScalars.startIndex
            var currentPosition = startPosition

            while currentPosition &lt; unicodeScalars.endIndex  {

                // get characters at current &amp; target positions then increment the current position
                let currentCharacter = unicodeScalars[currentPosition]
                let targetCharacter = target.unicodeScalars[targetPosition]

                print("target", targetCharacter, "current", currentCharacter)

                currentPosition = unicodeScalars.index(after: currentPosition)

                if currentCharacter == targetCharacter {
                    // if the current character matches the target character:
                    // - increment the target posistion
                    // - return the range if there are no more characters to match in the target
                    targetPosition = target.unicodeScalars.index(after: targetPosition)

                    if targetPosition == target.unicodeScalars.endIndex,
                        let start = startPosition.samePosition(in: self),
                        let end = currentPosition.samePosition(in: self) {

                        return start..&lt;end
                    }
                }
                else if targetPosition == target.unicodeScalars.startIndex || !exclusions.contains(currentCharacter) {
                    // if:
                    // - we're still at the start of the target; or
                    // - the current chracter isn't one of our valid exclusion characters
                    // then:
                    // - advance the start position and break out of the loop
                    startPosition = unicodeScalars.index(after: currentPosition)
                    break
                }
            }
        }
        return nil
    }
}


Testing

let messy = "Serial: YF 1942-B (Scanned)"

if let range = messy.range(of: "YF1942B", ignoring: CharacterSet.alphanumerics.inverted) {
    // -&gt; Range&lt;String.Index&gt;(8, 17)

    messy.substring(with: range)
    // -&gt; "YF 1942-B"
}