Swift 4字符串范围内的某个字符

时间:2018-03-30 10:04:51

标签: swift swift4 nsrange

我试图在字符串中创建一个从提供的字符串中删除某些字符的函数。

例如我有

"‌Boll %b‌ (Teeth ‌Alligator‌ (13,8,8,5,5,3,n),20,2,ma)"

我希望将其编辑为

"‌Boll %b‌"

表示删除"("")"

之间的所有内容

所以我做了这个功能

func deleteInnerString(with string: String, from firstCharacter: String, to secondCharacter: String) -> String {
    guard let leftIndex = (string.range(of: firstCharacter)?.lowerBound),
        let rightIndex = string.range(of: secondCharacter)?.lowerBound else {
            return string
    }
    let remainingString = String(string.prefix(upTo: leftIndex) + string.suffix(from: string.index(after: rightIndex)))
    return remainingString
}

但在这种情况下输出字符串是

"‌Boll %b‌ ,20,2,ma)"

问题是,我如何扫描字符串以找到最后一个右括号范围?

3 个答案:

答案 0 :(得分:3)

请注意,您的策略不适用于非嵌套括号。

E.g。这个输入

a(b)c(d)e

用你的方法会产生这个输出

ae

哪个恕我直言不正确。

解决方案

此解决方案将适用于嵌套非嵌套括号

let text = "‌a(b)c(d)e"
var numOfNestedParentesis = 0
var indexesToRemove:Set<Int> = []

for (index, char) in text.enumerated() {

    if char == "(" {
        numOfNestedParentesis += 1
    }

    if numOfNestedParentesis > 0 {
        indexesToRemove.insert(index)
    }

    if char == ")" {
        numOfNestedParentesis -= 1
    }
}

let result = String(text.enumerated()
    .filter { !indexesToRemove.contains($0.offset) }
    .map { $0.element } )

测试

print(result) // ‌ace

答案 1 :(得分:2)

可以为String.range函数提供额外选项,因此您可以将String.CompareOptions.backwards参数传递给最后一个实例。

func deleteInnerString(with string: String, from firstCharacter: String, to secondCharacter: String) -> String {
    guard let leftIndex = (string.range(of: firstCharacter)?.lowerBound),
        let rightIndex = string.range(of: secondCharacter, options: .backwards)?.lowerBound else {
            return string
    }
    let remainingString = String(string.prefix(upTo: leftIndex) + string.suffix(from: string.index(after: rightIndex)))
    return remainingString
}

答案 2 :(得分:1)

您必须在.backwards字符串函数中使用String.CompareOptions range选项。如下所示

func deleteString(with string: String, from firstCharacter: String, to secondCharacter: String) -> String {
    guard let leftIndex = (string.range(of: firstCharacter)?.lowerBound),
        let rightIndex = string.range(of: secondCharacter, options: .backwards)?.lowerBound else {
            return string
    }
    let remainingString = String(string.prefix(upTo: leftIndex) + string.suffix(from: string.index(after: rightIndex)))

    return remainingString.trimmingCharacters(in: .whitespaces)
}