下面的函数给定一个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>
无需将其转换为 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))
瑞士军队蒸汽铲,用于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)
}
}
要点在这里
将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)
}