Преобразовать диапазон<Int> в диапазон<String.Index>
Приведенная ниже функция NSString
удаляет теги HTML из этой строки и возвращает результат также в виде NSString
,
private func removeHTMLTags(source: NSString) -> NSString {
var range = NSMakeRange(0, 0)
let HTMLTags = "<[^>]*>"
var sourceString = source
while sourceString.rangeOfString(HTMLTags, options: NSStringCompareOptions.RegularExpressionSearch).location != NSNotFound {
range = sourceString.rangeOfString(HTMLTags, options: NSStringCompareOptions.RegularExpressionSearch)
sourceString = sourceString.stringByReplacingCharactersInRange(range, withString: "")
}
return sourceString;
}
Я пытаюсь переписать это на чистом Свифте. У меня проблема с Range
введите Свифт.
В оригинальной функции кода range
объявлена переменная типа NSRange
, В моей версии я не могу этого сделать, потому что линия sourceString.rangeOfString(HTMLTags, options: NSStringCompareOptions.RegularExpressionSearch)
внутри цикла while возвращает тип Range<String.Index>
и это дало бы мне ошибку. Невозможно преобразовать тип выражения '()' в тип 'NSRange'.
Итак, я объявил переменную, как это var range = Range(start: 0, end: 0)
но теперь я получаю пару новых ошибок.
Невозможно преобразовать тип выражения '()' в тип ошибки 'Range' в строке
range = sourceString.rangeOfString(HTMLTags, options: NSStringCompareOptions.RegularExpressionSearch)
И "Int" не совпадает с "String.Index" в строке
sourceString = sourceString.stringByReplacingCharactersInRange(range, withString: "")
Я искал решение для этого и наткнулся на этот пост. Затем я изменил range
объявление переменной к этому.
var range = Range<String.Index>(start: 0, end: 0)
Но я получаю эту новую ошибку сейчас! Дополнительный аргумент "конец" в вызове
Я не могу найти способ решить эту проблему. Может кто-нибудь помочь, пожалуйста?
Спасибо.
5 ответов
Свифт String
метод rangeOfString()
возвращает необязательный Range?
который не имеет location
свойство, но можно проверить с помощью условного связывания (if let
).
И если вы замените NSString
метод stringByReplacingCharactersInRange()
Свифт String
метод replaceRange()
(или в этом случае просто removeRange()
) тогда вы можете работать чисто с Range<Swift.Index>
без преобразования его в NSRange
или же Range<Int>
,
func removeHTMLTags(source : String) -> String {
var sourceString = source
let HTMLTags = "<[^>]*>"
while let range = sourceString.rangeOfString(HTMLTags, options: .RegularExpressionSearch) {
sourceString.removeRange(range)
}
return sourceString;
}
Для людей, как я, которые действительно хотят получить Range<String.Index>
:
func convert(range: Range<Int>, string: String) -> Range<String.Index>
{
return Range<String.Index>(start: advance(string.startIndex, range.startIndex),
end: advance(string.startIndex, range.endIndex))
}
Вам нужно ссылаться на строку, где вы будете использовать диапазон.
В Swift 2 дано string: String
а также nsRange: NSRange
, это
let range = Range(start: string.startIndex.advancedBy(nsRange.location),
end: string.startIndex.advancedBy(nsRange.location+nsRange.length))
Перерабатывать NSRange
в Range<String.Index>
быстрая функция
func rangeWithString(string : String, range : NSRange) -> Range<String.Index> {
return string.startIndex.advancedBy(range.location) ..< string.startIndex.advancedBy(range.location+range.length)
}
Швейцарская паровая лопата для String
индексирование, NSRange
, Range<Int|String.Index>
преобразования
import Foundation
func +<T: IntegerType>(lhs: String.Index, rhs: T) -> String.Index {
var r = lhs
var x = rhs
while x > 0 { // advance() won't work because IntegerType and String.Index are incompatible
r = r.successor()
x--
}
while x < 0 {
r = r.predecessor()
x++
}
return r
}
func -<T: IntegerType>(lhs: String.Index, rhs: T) -> String.Index {
var r = lhs
var x = rhs
while x > 0 {
r = r.predecessor()
x--
}
while x < 0 {
r = r.successor()
x++
}
return r
}
extension NSRange {
init(range: Range<Int>) {
location = range.startIndex
length = range.endIndex - range.startIndex
}
var range: Range<Int> { return Range<Int>(start: location, end: location + length) }
}
extension String {
var nsrange: NSRange { return NSMakeRange(0, count(self)) }
var range: Range<Int> { return Range<Int>(start: 0, end: count(self)) }
subscript (index: Int) -> String {
return self[index...index]
}
subscript (index: Int) -> Character {
return self[index] as Character
}
subscript (range: Range<String.Index>) -> String {
return substringWithRange(range)
}
subscript (range: NSRange) -> String {
return self[toStringRange(range)]
}
// allows "abcd"[0...1] // "ab"
subscript (range: Range<Int>) -> String {
return self[toStringRange(range)]
}
func toStringRange(range: NSRange) -> Range<String.Index> {
return toStringRange(range.range)
}
func toStringRange(range: Range<Int>) -> Range<String.Index> {
let start = startIndex + max(range.startIndex, 0)
let end = startIndex + min(range.endIndex, count(self))
return Range<String.Index>(start: start, end: end)
}
}