首页 > 解决方案 > Swift 4.2 使用多个字符提取子字符串是分隔符

问题描述

我是 Swift 新手,在浏览了 Apple 文档和其他来源后,我不清楚如何使用多个字符作为分隔符来提取子字符串。例如:我有一个字符串,看起来像:

A.1 值1 B.2 值2 E 值3 C 值4

并且需要将值 1 - 4 分配给不同的变量。

标签: iosswiftstring

解决方案


我喜欢这种事情的正则表达式。

我将按照字面意思告诉您,并假设要找到的子字符串前面有"A.1", "B.2","E""C", 并且前面和后面都有一个空格,除了最后一个子字符串后面是原始字符串的结尾。此外,我将非常简单地假设分隔符如"E"不能以任何其他方式出现在我们的字符串中。然后我们可以使用适当的模式捕获每个子字符串:

let s = "A.1 harpo B.2 chico E zeppo C groucho"
let p1 = "^A\\.1 (.*) B\\.2 "
let p2 = " B\\.2 (.*) E "
let p3 = " E (.*) C "
let p4 = " C (.*)$"
let patts = [p1,p2,p3,p4]
var result = [String]()
for patt in patts {
    let regex = try! NSRegularExpression(pattern: patt, options: [])
    if let match = regex.firstMatch(in: s, options: [], 
        range: NSRange(s.startIndex..<s.endIndex, in: s)) {
            let r = match.range(at: 1)
            result.append((s as NSString).substring(with: r))
    }
}
// result is now ["harpo", "chico", "zeppo", "groucho"]

我们现在将四个所需的子字符串提取到一个数组中,从那里处理它们是微不足道的。

请注意,我们没有对空间做出任何假设。即使目标子字符串包含空格,上述方法也能很好地工作,因为我们只对分隔符有吸引力。例如,如果原始字符串是

let s = "A.1 the rain B.2 in spain E stays mainly C in the plain"

然后result是数组

["the rain", "in spain", "stays mainly", "in the plain"]

然而,我应该指出,做这种事情的另一种方法是用扫描仪遍历原始字符串。你可能更喜欢这个,因为这里真的不需要正则表达式,如果你不知道正则表达式,你会发现这种走得更清楚。所以这里改写为使用扫描仪。请注意,我们最终得到了四个 Optional NSString 对象,因为 Scanner 实际上是 Objective-C Cocoa Foundation 的东西,但根据需要将它们转换为 String 对象并不难:

let s = "A.1 the rain B.2 in spain E stays mainly C in the plain"
let scan = Scanner(string: s)
scan.scanString("A.1 ", into: nil)
var r1 : NSString? = nil
scan.scanUpTo(" B.2 ", into: &r1)
scan.scanString("B.2 ", into: nil)
var r2 : NSString? = nil
scan.scanUpTo(" E ", into: &r2)
scan.scanString("E ", into: nil)
var r3 : NSString? = nil
scan.scanUpTo(" C ", into: &r3)
scan.scanString("C ", into: nil)
var r4 : NSString? = 
    (scan.string as NSString).substring(from: scan.scanLocation) as NSString
r1 // the rain
r2 // in spain
r3 // stays mainly
r4 // in the plain

推荐阅读