将范围<Int>转换为范围<字符串>



下面的函数给定一个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;
}

我正在尝试用纯 Swift 重写它。我在 Swift 中面临 Range 类型的问题。

在原始代码函数中,range变量声明为NSRange类型。在我的版本中,我无法这样做,因为 while 循环内sourceString.rangeOfString(HTMLTags, options: NSStringCompareOptions.RegularExpressionSearch)行返回类型 Range<String.Index> 它会给我错误无法将表达式的类型"()"转换为类型"NSRange"。

所以我像这样声明了var range = Range(start: 0, end: 0)变量,但现在我得到了几个新错误。

无法将表达式的类型"()"转换为行中的类型"范围"错误

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)

但是我现在收到这个新错误!调用中的额外参数"结束"

我想不出解决这个问题的方法。谁能帮忙?

谢谢。

Swift String 方法rangeOfString()返回一个可选Range?,其中没有 location 属性,但可以使用条件绑定 (if let ) 进行检查。

如果您替换NSString方法stringByReplacingCharactersInRange()通过 Swift String 方法replaceRange()(或在这种情况下只需通过removeRange() ),您就可以纯粹使用Range<Swift.Index>无需将其转换为 NSRangeRange<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: StringnsRange: NSRange ,这是

let range = Range(start: string.startIndex.advancedBy(nsRange.location),
    end: string.startIndex.advancedBy(nsRange.location+nsRange.length))

瑞士军队蒸汽铲,用于String下标、NSRangeRange<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)
    }
}

要点在这里

NSRange转换为 swift 函数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)
}

最新更新