Swift: String firstIndex after character
Swift: String firstIndex after character
我正在尝试检测字符串上的括号,例如:foo(bar)baz(blim)
并反转括号内的内容,但我的实现超出了反弹范围:
func reverseInParentheses(inputString: String) -> String {
var tmpStr = inputString
var done = false
while !done {
if let lastIndexOfChar = tmpStr.lastIndex(of: "(") {
let startIndex = tmpStr.index(lastIndexOfChar, offsetBy:1)
if let index = tmpStr.firstIndex(of: ")") {
let range = startIndex..<index
let strToVerse = String(tmpStr[range])
let reversedStr = reverseStr(str: strToVerse)
tmpStr = tmpStr.replacingOccurrences(of: "(" + strToVerse + ")", with: reversedStr)
}
} else {
done = true
}
}
return tmpStr
}
我怎样才能在 startIndex
之后得到 tmpStr.firstIndex(of: ")")
你们知道怎么做吗?
how can I get the tmpStr.firstIndex(of: ")")
after the startIndex
?
执行此操作的一种方法是“剪切”startIndex
处的字符串,并获取后半部分。然后在子字符串上使用 firstIndex(of:)
。由于 Substring
只是对原始字符串的“视图”,因此 firstIndexOf
仍然是原始字符串的 returns 索引。
let string = "foo(bar)baz(blim)"
if let lastIndexOfChar = string.lastIndex(of: "(") {
let startIndex = string.index(after: lastIndexOfChar)
let substring = string[startIndex..<string.endIndex] // cut off the first part of the string.
// now you have a "Substring" object
if let indexAfterOpenBracket = substring.firstIndex(of: ")") {
// prints "blim", showing that the index is indeed from the original string
print(string[startIndex..<indexAfterOpenBracket])
}
}
你可以把这个写成扩展:
extension StringProtocol {
func firstIndex(of char: Character, after index: Index) -> Index? {
let substring = self[index..<endIndex]
return substring.firstIndex(of: char)
}
}
现在,如果您在 reverseInParentheses
中调用 tmpStr.firstIndex(of: ")", after: startIndex)
,它应该可以工作。
您可以迭代您的字符串,保留一个索引作为参考,以将其与 endIndex 进行比较。因此,每次您成功找到一个范围时,您都会在结束索引之后开始进行新的搜索。顺便说一句,您不应该使用 replacingOccurrences,因为它也可能会替换不在括号内的单词。您可以使用 RangeReplaceableCollection replaceSubrange
并将反转的子字符串传递给该方法。
要查找字符后的第一个索引,您可以扩展集合,return 如果找到元素的第一个索引后的索引:
extension Collection where Element: Equatable {
func firstIndex(after element: Element) -> Index? {
guard let index = firstIndex(of: element) else { return nil }
return self.index(after: index)
}
}
您的方法应如下所示:
func reverseInParentheses(inputString: String) -> String {
var inputString = inputString
var startIndex = inputString.startIndex
while startIndex < inputString.endIndex,
let start = inputString[startIndex...].firstIndex(after: "("),
let end = inputString[start...].firstIndex(of: ")") {
inputString.replaceSubrange(start..<end, with: inputString[start..<end].reversed())
startIndex = inputString.index(after: end)
}
return inputString
}
let str = "foo(bar)baz(blim)"
reverseInParentheses(inputString: str) // "foo(rab)baz(milb)"
或扩展StringProtocol
并将Self
限制为RangeReplaceableCollection
:
extension StringProtocol where Self: RangeReplaceableCollection {
var reversingSubstringsBetweenParentheses: Self {
var startIndex = self.startIndex
var source = self
while startIndex < endIndex,
let start = source[startIndex...].firstIndex(after: "("),
let end = source[start...].firstIndex(of: ")") {
source.replaceSubrange(start..<end, with: source[start..<end].reversed())
startIndex = index(after: end)
}
return source
}
}
let str = "foo(bar)baz(blim)"
str.reversingSubstringsBetweenParentheses // "foo(rab)baz(milb)"
更新了 Leo Dabus 的答案,以防在最后一个括号后写了更多文本。
func reverseInParentheses(_ str: String) -> String {
var str = str
var startIndex = str.startIndex
Var lastIndexOfChar = str.lastIndex(of: ")") ?? startIndex
while startIndex < lastIndexOfChar {
let start = str[startIndex...].firstIndex(after: "("),
let end = str[start...].firstIndex(of: ")") {
str.replaceSubrange(start..<end, with: str[start..<end].reversed())
startIndex = str.index(after: end)
}
return str
}
我正在尝试检测字符串上的括号,例如:foo(bar)baz(blim)
并反转括号内的内容,但我的实现超出了反弹范围:
func reverseInParentheses(inputString: String) -> String {
var tmpStr = inputString
var done = false
while !done {
if let lastIndexOfChar = tmpStr.lastIndex(of: "(") {
let startIndex = tmpStr.index(lastIndexOfChar, offsetBy:1)
if let index = tmpStr.firstIndex(of: ")") {
let range = startIndex..<index
let strToVerse = String(tmpStr[range])
let reversedStr = reverseStr(str: strToVerse)
tmpStr = tmpStr.replacingOccurrences(of: "(" + strToVerse + ")", with: reversedStr)
}
} else {
done = true
}
}
return tmpStr
}
我怎样才能在 startIndex
之后得到 tmpStr.firstIndex(of: ")")
你们知道怎么做吗?
how can I get the
tmpStr.firstIndex(of: ")")
after thestartIndex
?
执行此操作的一种方法是“剪切”startIndex
处的字符串,并获取后半部分。然后在子字符串上使用 firstIndex(of:)
。由于 Substring
只是对原始字符串的“视图”,因此 firstIndexOf
仍然是原始字符串的 returns 索引。
let string = "foo(bar)baz(blim)"
if let lastIndexOfChar = string.lastIndex(of: "(") {
let startIndex = string.index(after: lastIndexOfChar)
let substring = string[startIndex..<string.endIndex] // cut off the first part of the string.
// now you have a "Substring" object
if let indexAfterOpenBracket = substring.firstIndex(of: ")") {
// prints "blim", showing that the index is indeed from the original string
print(string[startIndex..<indexAfterOpenBracket])
}
}
你可以把这个写成扩展:
extension StringProtocol {
func firstIndex(of char: Character, after index: Index) -> Index? {
let substring = self[index..<endIndex]
return substring.firstIndex(of: char)
}
}
现在,如果您在 reverseInParentheses
中调用 tmpStr.firstIndex(of: ")", after: startIndex)
,它应该可以工作。
您可以迭代您的字符串,保留一个索引作为参考,以将其与 endIndex 进行比较。因此,每次您成功找到一个范围时,您都会在结束索引之后开始进行新的搜索。顺便说一句,您不应该使用 replacingOccurrences,因为它也可能会替换不在括号内的单词。您可以使用 RangeReplaceableCollection replaceSubrange
并将反转的子字符串传递给该方法。
要查找字符后的第一个索引,您可以扩展集合,return 如果找到元素的第一个索引后的索引:
extension Collection where Element: Equatable {
func firstIndex(after element: Element) -> Index? {
guard let index = firstIndex(of: element) else { return nil }
return self.index(after: index)
}
}
您的方法应如下所示:
func reverseInParentheses(inputString: String) -> String {
var inputString = inputString
var startIndex = inputString.startIndex
while startIndex < inputString.endIndex,
let start = inputString[startIndex...].firstIndex(after: "("),
let end = inputString[start...].firstIndex(of: ")") {
inputString.replaceSubrange(start..<end, with: inputString[start..<end].reversed())
startIndex = inputString.index(after: end)
}
return inputString
}
let str = "foo(bar)baz(blim)"
reverseInParentheses(inputString: str) // "foo(rab)baz(milb)"
或扩展StringProtocol
并将Self
限制为RangeReplaceableCollection
:
extension StringProtocol where Self: RangeReplaceableCollection {
var reversingSubstringsBetweenParentheses: Self {
var startIndex = self.startIndex
var source = self
while startIndex < endIndex,
let start = source[startIndex...].firstIndex(after: "("),
let end = source[start...].firstIndex(of: ")") {
source.replaceSubrange(start..<end, with: source[start..<end].reversed())
startIndex = index(after: end)
}
return source
}
}
let str = "foo(bar)baz(blim)"
str.reversingSubstringsBetweenParentheses // "foo(rab)baz(milb)"
更新了 Leo Dabus 的答案,以防在最后一个括号后写了更多文本。
func reverseInParentheses(_ str: String) -> String {
var str = str
var startIndex = str.startIndex
Var lastIndexOfChar = str.lastIndex(of: ")") ?? startIndex
while startIndex < lastIndexOfChar {
let start = str[startIndex...].firstIndex(after: "("),
let end = str[start...].firstIndex(of: ")") {
str.replaceSubrange(start..<end, with: str[start..<end].reversed())
startIndex = str.index(after: end)
}
return str
}