我在理解如何使用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。然后它使用安德鲁的魔法解析一切。我重命名了变量并使它们更清晰,这样你就可以看到哪个变量在过程中做了什么。然后最后,它返回解析后的字符串。
答案 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)
}