简体   繁体   English

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

[英]Swift 4 string range of a certain character

I'm trying to make a function in string that deletes some characters from a provided string. 我正在尝试使字符串中的功能从提供的字符串中删除一些字符。

For example i have 例如我有

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

and i want to edit this to 我想编辑这个

"‌Boll %b‌"

which means to delete everything between the "(" and ")" 这意味着删除"("")"之间的所有内容

So i've made this function 所以我做了这个功能

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
}

but in this case the output string is 但是在这种情况下,输出字符串是

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

The question is, how can i scan the string to find the last closing parenthesis range?? 问题是,如何扫描字符串以找到最后一个右括号范围?

Please note that your strategy won't work with non nested parenthesis. 请注意,您的策略不适用于非嵌套括号。

Eg this input 例如此输入

a(b)c(d)e

With your approach will produce this output 用您的方法将产生此输出

ae

Which IMHO is not correct. 哪个恕我直言不正确。

Solution

This solution instead will work with nested and non nested parenthesis 相反,此解决方案将适用于嵌套非嵌套括号

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 } )

Test 测试

print(result) // ‌ace

The String.range function can be provided extra options, so you can pass it the String.CompareOptions.backwards parameters to get the last instance. 可以为String.range函数提供其他选项,因此您可以String.CompareOptions.backwards传递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
}

You have to use .backwards option for String.CompareOptions in range function of string. 您必须在字符串的range函数中为String.CompareOptions使用.backwards选项。 as like below 如下

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)
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM