斯威夫特的子串

时间:2015-01-04 04:00:42

标签: swift substring

我在理解如何使用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
}

没有什么太复杂的。它接收一个包含标签的String。然后它使用安德鲁的魔法解析一切。我重命名了变量并使它们更清晰,这样你就可以看到哪个变量在过程中做了什么。然后最后,它返回解析后的字符串。

2 个答案:

答案 0 :(得分:2)

你可以做这样的事情,但事实并非如此。显然,您希望将其纳入函数并可能允许各种开始/结束标记。

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, { $0 == "<" })
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, { $0 != "" })) { $0! }

最后它使用了更多的功能风格。与Haskell相比,我不太确定我喜欢Swift风格的地图/过滤器。但无论如何,一个有潜在危险的部分是在最后的map中被迫展开。如果您可以使用[String?]的结果,那么就没有必要。

答案 1 :(得分:0)

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

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: "$1")
    println(result)
}