Удалить повторяющуюся подстроку из строки

#ios #swift #nsstring

#iOS #swift #nsstring

Вопрос:

Я не могу придумать функцию для удаления повторяющейся подстроки из моей строки. Моя строка выглядит так:

 "<bold><bold>Rutger</bold> Roger</bold> rented a <bold>testitem zero dollars</bold> from <bold>Rutger</bold>."
  

И если <bold> за ней следует другая <bold> , я хочу удалить вторую <bold> . При удалении этой второй <bold> я также хочу удалить первую </bold> , которая следует.

Итак, результат, который я ищу, должен быть таким:

 "<bold>Rutger Roger</bold> rented a <bold>testitem zero dollars</bold> from <bold>Rutger</bold>."
  

Кто-нибудь знает, как добиться этого в Swift (2.2)?

Комментарии:

1. Что вы хотите от string ?

2. Отредактировал исходное сообщение с ожидаемым результатом.

3. Первый <жирный> и первый </bold>

4. Действительно первый? Что, если входные данные "<bold>foo<bold>bar</bold>baz</bold>" ?

5. Если сбалансированные теги приводят к сбою вашего фреймворка, то проблема заключается в фреймворке, а не в HTML-файле.

Ответ №1:

Я написал решение с использованием регулярных выражений, предполагая, что теги не будут появляться во вложенном содержимом более 1 раза. Другими словами, он просто очищает двойные теги, не более того. Вы можете использовать тот же код и рекурсивный вызов, чтобы очистить столько вложенных повторяющихся тегов, сколько захотите:

 class Cleaner {

    var tags:Array<String> = [];

    init(tags:Array<String>) {
        self.tags = tags;
    }

    func cleanString(html:String) -> String {

        var res = html

        do {

            for tag in tags {

                let start = "<(tag)>"
                let end = "</(tag)>"

                let pattern = "(start)(.*?)(end)"

                let regex = try NSRegularExpression(pattern: pattern, options: NSRegularExpression.Options.caseInsensitive)

                let matches = regex.matches(in: res, options: [], range: NSRange(location: 0, length: res.utf16.count))

                var diff = 0;
                for match in matches {

                    let outer_range = NSMakeRange(match.rangeAt(0).location - diff, match.rangeAt(0).length)
                    let inner_range = NSMakeRange(match.rangeAt(1).location - diff, match.rangeAt(1).length)
                    let node = (res as NSString).substring(with: outer_range)
                    let content = (res as NSString).substring(with: inner_range)

                    // look for the starting tag in the content of the node
                    if content.range(of: start) != nil {
                        res = (res as NSString).replacingCharacters(in: outer_range, with: content);

                        //for shifting future ranges
                        diff  = (node.utf16.count - content.utf16.count)
                    }
                }
            }
        }
        catch {
            print("regex was bad!")
        }

        return res
    }
}

let cleaner = Cleaner(tags: ["bold"]);
let html = "<bold><bold>Rutger</bold> Roger</bold> rented a <bold><bold>testitem</bold> zero dollars</bold> from <bold>Rutger</bold>."

let cleaned = cleaner.cleanString(html: html)
print(cleaned)
//<bold>Rutger Roger</bold> rented a <bold>testitem zero dollars</bold> from <bold>Rutger</bold>.
  

Ответ №2:

Попробуйте это, я только что сделал. Надеюсь, это полезно.

 class Test : NSObject {
    static func removeFirstString (originString: String, removeString: String, withString: String) -> String {
        var genString = originString
        if originString.contains(removeString) {
            let range = originString.range(of: removeString)
            genString = genString.replacingOccurrences(of: removeString, with: withString, options: String.CompareOptions.anchored, range: range)
        }
        return genString
    }
}

var newString = Test.removeFirstString(originString: str, removeString: "<bold>", withString: "")

newString =  Test.removeFirstString(originString: newString, removeString: "</bold>", withString: "")
  

Комментарии:

1. Ну, GJ, но я не думаю, что это безопасно. Потому что иногда удаление rep. subs. разбалансирует HTML. Например: <t><t>x</t><y>b</y></t> результат вашего алгоритма <t>x</t><y>b</y></t> несбалансирован.