string替换不带NSString API的子字符串

时间:2017-05-06 22:32:11

标签: swift

我希望能够在没有桥接到NS类的情况下在本机Swift字符串中查找和替换子字符串的出现。我怎么能做到这一点?

这不是this question的重复,因为该问题是关于替换单个字符。这个问题是关于查找和替换可能包含许多字符的子字符串。

2 个答案:

答案 0 :(得分:3)

没有Foundation的方法:

extension String {
    func replacing(_ oldString: String, with newString: String) -> String {

        guard !oldString.isEmpty, !newString.isEmpty else { return self }

        let charArray = Array(self.characters)
        let oldCharArray = Array(oldString.characters)
        let newCharArray = Array(newString.characters)

        var matchedChars = 0
        var resultCharArray = [Character]()

        for char in charArray {
            if char == oldCharArray[matchedChars] {
                matchedChars += 1
                if matchedChars == oldCharArray.count {
                    resultCharArray.append(contentsOf: newCharArray)
                    matchedChars = 0
                }
            } else {
                for i in 0 ..< matchedChars {
                    resultCharArray.append(oldCharArray[i])
                }
                if char == oldCharArray[0] {
                    matchedChars = 1
                } else {
                    matchedChars = 0
                    resultCharArray.append(char)
                }
            }
        }

        return String(resultCharArray)

    }
}

使用示例:

let myString = "Hello World HelHelloello Hello HellHellooo"
print(myString.replacing("Hello", with: "Hi"))

输出:

Hi World HelHiello Hi HellHioo

使用Foundation的方法:

您可以在replacingOccurrences结构上使用String方法。

let myString = "Hello World"
let newString = myString.replacingOccurrences(of: "World", with: "Everyone")
print(newString) // prints "Hello Everyone"

答案 1 :(得分:2)

通用和纯粹的Swift方法

func splitBy<T: RangeReplaceableCollection>(_ s:T, by:T)->[T] where T.Iterator.Element:Equatable {
    var tmp = T()
    var res = [T]()
    var i:T.IndexDistance = 0
    let count = by.count

    var pc:T.Iterator.Element {
        get {
            i %= count
            let idx = by.index(by.startIndex, offsetBy: i)
            return by[idx]
        }
    }

    for sc in s {
        if sc != pc {
            i = 0
            if sc != pc {
            } else {
                i = i.advanced(by: 1)
            }
        } else {
            i = i.advanced(by: 1)
        }
        tmp.append(sc)
        if i == count {
            tmp.removeSubrange(tmp.index(tmp.endIndex, offsetBy: -i)..<tmp.endIndex)
            res.append(tmp)
            tmp.removeAll()
        }
    }

    res.append(tmp)
    return res
}

func split(_ s:String, by:String)->[String] {
    return splitBy(s.characters, by: by.characters).map(String.init)
}


extension RangeReplaceableCollection where Self.Iterator.Element: Equatable {
    func split(by : Self)->[Self]  {
        return splitBy(self, by: by)
    }
}

如何使用它?

let str = "simple text where i would like to replace something with anything"
let pat = "something"
let rep = "anything"

let s0 = str.characters.split(by: pat.characters).map(String.init)
let res = s0.joined(separator: rep)
print(res) // simple text where i would like to replace anything with anything

let res2 = split(str, by: pat).joined(separator: rep)
print(res2) // simple text where i would like to replace anything with anything

let arr = [1,2,3,4,1,2,3,4,1,2,3]
let p = [4,1]
print(arr.split(by: p)) // [[1, 2, 3], [2, 3], [2, 3]]