Swift 将 "abc1.23.456.7890xyz" 拆分为 "abc"、“1”、“23”、“456”、“7890” 和 "xyz"

Swift splitting "abc1.23.456.7890xyz" into "abc", "1", "23", "456", "7890" and "xyz"

在 Swift on OS X 我试图将字符串 "abc1.23.456.7890xyz" 分成这些字符串:

"abc"
"1"
"23"
"456"
"7890"
"xyz"

但是当我 运行 以下代码时,我得到以下内容:

=> "abc1.23.456.7890xyz"
(0,3) -> "abc"
(3,1) -> "1"
(12,4) -> "7890"
(16,3) -> "xyz"

这意味着应用程序正确找到了 "abc",第一个标记为“1”,但随后找到的下一个标记是“7890”(遗漏了“23”和“456”),然后是 "xyz".

谁能看到如何更改代码以找到所有字符串(包括“23”和“456”)?

非常感谢。

import Foundation
import XCTest

public
class WhosebugTest: XCTestCase {
    public
    func testRegex() {
        do {
            let patternString = "([^0-9]*)([0-9]+)(?:\.([0-9]+))*([^0-9]*)"
            let regex = try NSRegularExpression(pattern: patternString, options: [])

            let string = "abc1.23.456.7890xyz"
            print("=> \"\(string)\"")

            let range = NSMakeRange(0, string.characters.count)
            regex.enumerateMatchesInString(string, options: [], range: range) {
                (textCheckingResult, _, _) in
                if let textCheckingResult = textCheckingResult {
                    for nsRangeIndex in 1 ..< textCheckingResult.numberOfRanges {
                        let nsRange = textCheckingResult.rangeAtIndex(nsRangeIndex)
                        let location = nsRange.location
                        if location < Int.max {
                            let startIndex = string.startIndex.advancedBy(location)
                            let endIndex = startIndex.advancedBy(nsRange.length)
                            let value = string[startIndex ..< endIndex]
                            print("\(nsRange) -> \"\(value)\"")
                        }
                    }
                }
            }
        } catch {
        }
    }
}

一切都与您的正则表达式模式有关。您想要查找一系列连续的字母或数字。试试这个模式:

let patternString = "([a-zA-Z]+|\d+)"

另一种'Swifty'方式

let str = "abc1.23.456.7890xyz"
let chars = str.characters.map{ [=10=] }

enum CharType {
    case Number
    case Alpha
    init(c: Character) {
        self = .Alpha
        if isNumber(c) {
            self = .Number
        }
    }
    func isNumber(c: Character)->Bool {
        return "1234567890".characters.map{ [=10=] }.contains(c)
    }    
}

var tmp = ""
tmp.append(chars[0])
var type = CharType(c: chars[0])

for i in 1..<chars.count {
    let c = CharType(c: chars[i])

    if c != type {
        tmp.append(Character("."))
    }
    tmp.append(chars[i])
    type = c
}
tmp.characters.split(".", maxSplit: Int.max, allowEmptySlices: false).map(String.init)
// ["abc", "1", "23", "456", "7890", "xyz"]