在Swift中使用多个分隔符拆分字符串

krugob8w  于 2023-04-19  发布在  Swift
关注(0)|答案(7)|浏览(200)

我尝试在Swift(1.2)中使用多个分隔符或苹果称之为分隔符来拆分(或分解)字符串。
我的字符串看起来像这样:

KEY1=subKey1=value&subkey2=valueKEY2=subkey1=value&subkey2=valueKEY3=subKey1=value&subkey3=value

为了便于阅读,我把它格式化了:

KEY1=subKey1=value&subkey2=value
KEY2=subkey1=value&subkey2=value
KEY3=subKey1=value&subkey3=value

大写的“KEY”是预定义的名称。
我尝试使用以下命令来实现:

var splittedString = string.componentsSeparatedByString("KEY1")

但正如你所看到的,我只能用一个KEY作为分隔符来完成这一点,所以我正在寻找这样的东西:

var splittedString = string.componentsSeperatedByStrings(["KEY1", "KEY2", "KEY3"])

所以结果是:

[
  "KEY1" => "subKey1=value&subkey2=value",
  "KEY2" => "subkey1=value&subkey2=value",
  "KEY3" => "subkey1=value&subkey2=value"
]

Swift 1.2中有什么内置的东西可以使用吗?或者有什么扩展/库可以轻松做到这一点?
谢谢你的时间,并有一个伟大的一天!

lyfkaqu1

lyfkaqu11#

如果键是单个字符,也可以使用以下方法来拆分具有多个分隔符的字符串:

//swift 4+
let stringData = "K01L02M03"
let res = stringData.components(separatedBy: CharacterSet(charactersIn: "KLM"))

//older swift syntax
let res = stringData.componentsSeparatedByCharactersInSet(NSCharacterSet(charactersInString: "KLM"));

res将包含["01", "02", "03"]
如果任何人知道任何一种特殊的语法来扩展这种方法到每个键多个字符,欢迎您提出建议并改进这个答案

92vpleto

92vpleto2#

Swift 4.2更新到@vir us的答案:

let string = "dots.and-hyphens"
let array = string.components(separatedBy: CharacterSet(charactersIn: ".-"))
jtw3ybtb

jtw3ybtb3#

这不是很有效,但它应该做的工作:

import Foundation

extension String {
  func componentsSeperatedByStrings(ss: [String]) -> [String] {
    let inds = ss.flatMap { s in
      self.rangeOfString(s).map { r in [r.startIndex, r.endIndex] } ?? []
    }
    let ended = [startIndex] + inds + [endIndex]
    let chunks = stride(from: 0, to: ended.count, by: 2)
    let bounds = map(chunks) { i in (ended[i], ended[i+1]) }
    return bounds
      .map { (s, e) in self[s..<e] }
      .filter { sl in !sl.isEmpty }
  }
}


"KEY1=subKey1=value&subkey2=valueKEY2=subkey1=value&subkey2=valueKEY3=subKey1=value&subkey3=value".componentsSeperatedByStrings(["KEY1", "KEY2", "KEY3"])

// ["=subKey1=value&subkey2=value", "=subkey1=value&subkey2=value", "=subKey1=value&subkey3=value"]

或者,如果你想用字典的形式:

import Foundation

extension String {
  func componentsSeperatedByStrings(ss: [String]) -> [String:String] {
    let maybeRanges = ss.map { s in self.rangeOfString(s) }
    let inds   = maybeRanges.flatMap { $0.map { r in [r.startIndex, r.endIndex] } ?? [] }
    let ended  = [startIndex] + inds + [endIndex]
    let chunks = stride(from: 0, to: ended.count, by: 2)
    let bounds = map(chunks) { i in (ended[i], ended[i+1]) }
    let values = bounds
      .map { (s, e) in self[s..<e] }
      .filter { sl in !sl.isEmpty }
    let keys = filter(zip(maybeRanges, ss)) { (r, _) in r != nil }
    var result: [String:String] = [:]
    for ((_, k), v) in zip(keys, values) { result[k] = v }
    return result
  }
}

"KEY1=subKey1=value&subkey2=valueKEY2=subkey1=value&subkey2=valueKEY3=subKey1=value&subkey3=value".componentsSeperatedByStrings(["KEY1", "KEY2", "KEY3"])

// ["KEY3": "=subKey1=value&subkey3=value", "KEY2": "=subkey1=value&subkey2=value", "KEY1": "=subKey1=value&subkey2=value"]

对于Swift 2:

import Foundation

extension String {
  func componentsSeperatedByStrings(ss: [String]) -> [String] {
    let unshifted = ss
      .flatMap { s in rangeOfString(s) }
      .flatMap { r in [r.startIndex, r.endIndex] }
    let inds  = [startIndex] + unshifted + [endIndex]
    return inds.startIndex
      .stride(to: inds.endIndex, by: 2)
      .map { i in (inds[i], inds[i+1]) }
      .flatMap { (s, e) in s == e ? nil : self[s..<e] }
  }
}
zsohkypk

zsohkypk4#

Swift 5:

extension String {
    func components<T>(separatedBy separators: [T]) -> [String] where T : StringProtocol {
        var result = [self]
        for separator in separators {
            result = result
                .map { $0.components(separatedBy: separator)}
                .flatMap { $0 }
        }
        return result
    }
}

它是用来装漂亮整洁的代码的,如果你需要高效的东西,就不要用它

at0kjp5o

at0kjp5o5#

Swift 2向前兼容
使用正则表达式:

let string  = "KEY1=subKey1=value&subkey2=valueKEY2=subkey1=value&subkey2=valueKEY3=subKey1=value&subkey3=value"
let nsString :NSString = string
let stringRange = NSMakeRange(0, string.utf16.count)
let pattern = "(KEY\\d)=([^=]+=[^&]+[^=]+?=[^K]+)"
var results = [String:String]()
do {
    var regEx = try NSRegularExpression(pattern:pattern, options:[])
    regEx.enumerateMatchesInString(string, options: [], range: stringRange) {
        (result : NSTextCheckingResult?, _, _) in
        if let result = result {
            if result.numberOfRanges == 3 {
                let key   = nsString.substringWithRange(result.rangeAtIndex(1))
                let value = nsString.substringWithRange(result.rangeAtIndex(2))
                results[key] = value
            }
        }
    }
}
catch {
    print("Bad Pattern")
}

结果:["KEY3": "subKey1=value&subkey3=value", "KEY2": "subkey1=value&subkey2=value", "KEY1": "subKey1=value&subkey2=value"]

1szpjjfi

1szpjjfi6#

你可以用正则表达式来实现。下面的代码片段有点笨拙,也不是真正的故障安全,但它应该能给予你一个想法。

let string = "KEY1=subKey1=value&subkey2=valueKEY2=subkey1=value&subkey2=valueKEY3=subKey1=value&subkey3=value"
let re = NSRegularExpression(pattern: "(KEY1|KEY2|KEY3)=", options: nil, error: nil)!
let matches = re.matchesInString(string, options: nil,
    range: NSMakeRange(0, count(string)))

var dict = [String: String]()

for (index, match) in enumerate(matches) {
    let key = (string as NSString).substringWithRange(
        NSMakeRange(match.range.location, match.range.length - 1))

    let valueStart = match.range.location + match.range.length
    let valueEnd = index < matches.count - 1 ? matches[index + 1].range.location
                                             : count(string)
    let value = (string as NSString).substringWithRange(
        NSMakeRange(valueStart, valueEnd - valueStart))

    dict[key] = value
}

dict的最终值为

[KEY3: subKey1=value&subkey3=value, 
 KEY2: subkey1=value&subkey2=value,
 KEY1: subKey1=value&subkey2=value]
goucqfw6

goucqfw67#

Swift提供了一个new function split here

let line = "BLANCHE:   I don't want realism. I want magic!"
print(line.split(whereSeparator: { $0 == " " || $0 == "."}))

相关问题