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