функция, чтобы найти все NSRange для строки в строке в Swift

Я хотел бы, чтобы все пары букв CG были красного цвета в последовательностях ДНК (строка). Я могу сделать это с помощью NSMutableAttributedString. Для этого мне нужны NSRanges всех позиций CG, и я попытался сделать функцию ниже, но в строке

indexesOfStringIn = (stringOut as NSString).rangeOfString(stringIn, options: 0, range: rangeForIndexStringIn) 

rangeOfString с диапазоном не может быть вызван со списком аргументов типа (String, параметры: Int, диапазон: NSRange). Где ошибка? Что я сделал не так?

func searchForNSRangesOfStringInString(stringOut: String, stringIn: String) -> [NSRange]

{
    var arrayOfindexesOfStringIn = [NSRange]()

if stringIn.characters.count > 1
{
    var rangeNS = (stringOut as NSString).rangeOfString(stringIn)

    if rangeNS.location != NSNotFound
    {
        let endIndexOfStringOut = (stringOut as NSString).length - 1
        var indexesOfStringIn = (stringOut as NSString).rangeOfString(stringIn)
        arrayOfindexesOfStringIn = [indexesOfStringIn]
        var lastIndexOfStringIn = (stringOut as NSString).rangeOfString(stringIn).location
        var rangeForIndexStringIn = NSRange(lastIndexOfStringIn...endIndexOfStringOut)

        while indexesOfStringIn.location != NSNotFound
        {
            indexesOfStringIn = (stringOut as NSString).rangeOfString(stringIn, options: 0, range: rangeForIndexStringIn)

            if indexesOfStringIn.location != NSNotFound
            {

                arrayOfindexesOfStringIn.append(indexesOfStringIn)

                lastIndexOfStringIn = (stringOut as NSString).rangeOfString(stringIn, options: 0, range: rangeForIndexStringIn).location

                rangeForIndexStringIn = NSRange(lastIndexOfStringIn...endIndexOfStringOut)

            }
        }
    }
}
return arrayOfindexesOfStringIn
} 

person VYT    schedule 27.09.2015    source источник
comment
Просто используйте NSRegularExpression   -  person uchuugaka    schedule 27.09.2015
comment
Хорошо, но в чем ошибка в моем коде? Наверное, это довольно просто, но я застрял.   -  person VYT    schedule 27.09.2015


Ответы (1)


Как было предложено uchuugaka, гораздо проще использовать NSRegularExpression для возврата массива диапазонов совпадений в строке следующим образом:

extension String {
    func findOccurencesOf(text text:String) -> [NSRange] {
        return !text.isEmpty ? try! NSRegularExpression(pattern: text, options: []).matchesInString(self, options: [], range: NSRange(0..<characters.count)).map{ $0.range } : []
    }
}

let str = "CGCGCGCGCG"

let ranges = str.findOccurencesOf(text: "CG")

print(ranges.count)   // 5

Просто добавьте управляющее событие для изменения редактирования текстового поля и прокрутите диапазоны следующим образом:

import UIKit

class ViewController: UIViewController {

    @IBOutlet weak var textField: UITextField!
    override func viewDidLoad() {
        super.viewDidLoad()
        textField.addTarget(self, action: "coloring:", forControlEvents: UIControlEvents.EditingChanged)
        textField.becomeFirstResponder()
    }
    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
    func coloring(sender:UITextField) {
        let attText = NSMutableAttributedString(string: sender.text ?? "")
        let ranges = sender.text!.uppercaseString.findOccurencesOf(text: "CG")
        for range in ranges {
            attText.addAttributes([NSForegroundColorAttributeName : UIColor.redColor()], range: range)
        }
        sender.attributedText = attText
    }

}

extension String {
    func findOccurencesOf(text text:String) -> [NSRange] {
        return !text.isEmpty ? try! NSRegularExpression(pattern: text, options: []).matchesInString(self, options: [], range: NSRange(0..<characters.count)).map{ $0.range } : []
    }
}
person Leo Dabus    schedule 27.09.2015
comment
Спасибо, хорошее решение, и, вероятно, я воспользуюсь им в конце! Я нахожусь в процессе обучения, поэтому я не могу понять, почему rangeOfString с диапазоном неверен, когда это должно быть нормально для NSString, это сбивает меня с толку :(. - person VYT; 27.09.2015
comment
что означает [ ] в опциях: ? - person VYT; 27.09.2015
comment
Означает то же, что и nil = без вариантов - person Leo Dabus; 27.09.2015
comment
Это пустой набор опций - person Leo Dabus; 27.09.2015
comment
!!! Раньше я использовал nil, и это было неправильно. Когда я начал использовать [ ] в опциях в rangeOfString(stringIn, options: [ ], range: rangeForIndexStringIn) я больше не жалуюсь! - person VYT; 27.09.2015
comment
Я позже выложу исправленный код, мне нужно решить еще одну проблему в этом коде. - person VYT; 27.09.2015