#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>
несбалансирован.