Swift 中的子串

Substrings in Swift

我无法理解如何使用 Swift 中的子字符串。基本上,我得到一个 JSON 值,它有一个具有以下格式的字符串:

<a href="#">Something</a>

我正在尝试使用 Swift 摆脱 HTML 锚标记,所以只剩下 Something。我的想法是找到字符串中每个 <> 的索引,这样我就可以做一个 substringWithRange 并前进到正确的索引。

我的问题是我不知道如何找到索引。我读到 Swift 不支持索引(除非你扩展它。)

我不想添加不必要的 CPU 循环。所以我的问题是,如何以不低效的方式找到索引?或者,有没有更好的过滤标签的方法?

编辑: 将 Andrew 的第一个代码示例转换为函数:

func formatTwitterSource(rawStr: String) -> String {
    let unParsedString = rawStr
    var midParseString = ""
    var parsedString = ""

    if let firstEndIndex = find(unParsedString, ">") {
        midParseString = unParsedString[Range<String.Index>(start: firstEndIndex.successor(), end: unParsedString.endIndex)]
        if let secondStartIndex = find(midParseString, "<") {
            parsedString = midParseString[Range<String.Index>(start: midParseString.startIndex, end: secondStartIndex)]
        }
    }          
    return parsedString
}

没什么太复杂的。它接受一个包含标签的字符串。然后它使用 Andrew 的魔法将所有内容解析出来。我重命名了变量并使它们更清晰,以便您可以看到哪个变量在过程中做了什么。然后最后,它 returns 解析后的字符串。

你可以做这样的事情,但它不是真的。显然,您希望将其分解为一个函数,并可能允许使用各种 start/end 标记。

let testText = "<a href=\"#\">Something</a>"
if let firstEndIndex = find(testText, ">") {
    let testText2 = testText[Range<String.Index>(start: firstEndIndex.successor(), end: testText.endIndex)]
    if let secondStartIndex = find(testText2, "<") {
        let testText3 = testText2[Range<String.Index>(start: testText2.startIndex, end: secondStartIndex)]
    }
}

编辑

进一步研究这个问题并想出一些更惯用的东西?

let startSplits = split(testText, { [=11=] == "<" })
let strippedValues = map(startSplits) { (s) -> String? in
    if let endIndex = find(s, ">") {
        return s[Range<String.Index>(start: endIndex.successor(), end: s.endIndex)]
    }
    return nil
}
let strings = map(filter(strippedValues, { [=11=] != "" })) { [=11=]! }

它在最后使用了一些更实用的风格。不确定与 Haskell 相比,我更喜欢 map/filter 的 Swift 风格。但无论如何,一个潜在危险的部分是在最后 map 中强制解包。如果您可以接受 [String?] 的结果,那么就没有必要了。

尽管这个问题已经得到解答,但我正在添加基于正则表达式的解决方案。

let pattern = "<.*>(.*)<.*>"
let src = "<a href=\"#\">Something</a>"
var error: NSError? = nil

var regex = NSRegularExpression(pattern: pattern, options: .DotMatchesLineSeparators, error: &error)

if let regex = regex {
    var result = regex.stringByReplacingMatchesInString(src, options: nil, range: NSRange(location:0,
    length:countElements(src)), withTemplate: "")
    println(result)
}