具有多组swift的正则表达式

问题描述 投票:0回答:1

即时通讯使用swift 4并与正则表达式捕获组有一些问题。

所以,我在这里有正则表达式:

let regex = try! NSRegularExpression(pattern:"Tambah saldo via (merchant|transfer (online|bank)).(\\w+ \\.?)($)?(((\\w+\\.)?\\w+? (\\w+ )?\\.) No Rek:([0-9]+(.[0-9])*).[^0-9]+([0-9]+))?", options: .caseInsensitive)

并有多个回应:

let response1 = "Tambah saldo via transfer bank BCA PT.BARRYPRIMA CORP . No Rek:427.123.444 . Jumlah transfer Rp.200864."
let response2 = "Tambah saldo via transfer online Bersama BARRYPRIMA CORP . No Rek:123456. Jumlah transfer Rp.200864."
let response3 = "Tambah saldo via transfer bank Mandiri BARRYPRIMA . No Rek:43512343598347. Jumlah transfer Rp.200864."
let response4 = "Tambah saldo via merchant Tito ."
let response5 = "Tambah saldo via merchant Bagaskara putra."

我想得到多个值,并将其存储到[String]即im的值

1:“银行转账”,“BCA”,“PT.BARRYPRIMA CORP”,“427,123,444”,“200864”

2:“在线转移”,“在一起”,“BARRYPRIMA CORP”,“123456”,“200864”

3:“银行转账”,“Mandiri”,“BARRYPRIMA”,“43512343598347”,“200864”

4:“商人”,“铁托”

5:“商人”,“bagaskara putra”

我试过this one的功能

并得到这个错误

线程1:致命错误:下标:子范围扩展到字符串结束

swift regex swift4
1个回答
1
投票

首先,您需要修改正则表达式模式,以获得您描述的预期捕获。

  • 使用(?:...)抑制一些捕获
  • 你的模式有一些缺点,例如([0-9]+(.[0-9])*)427.123.444不匹配

我懂了:

let regex = try! NSRegularExpression(pattern:"Tambah saldo via (merchant|transfer (?:online|bank)).(?:(\\w+(?:\\s*\\w+)*)\\.$|(\\w+)\\s+)(?:(?:((?:\\w+\\.)?\\w+?(?:\\s+\\w+)?)\\s+\\.) No Rek:([0-9]+(?:\\.[0-9]+)*)\\s*\\.[^0-9]+([0-9]+))?", options: .caseInsensitive)

但是你可能需要修改更多的部分,因为我不明白.是如何工作的。

我不明白为什么这个输入:

let response5 = "Tambah saldo via merchant Bagaskara putra."

产生:

5: "merchant","bagaskara putra"

不是“商人”,“Bagaskara”,“putra”吗? (我的意思是3元素。)


但是你的问题是如何将多个捕获返回到一个字符串数组,而不是为你的目的找到合适的模式。

所以,我使用上面的正则表达式进行测试。


你得到致命错误的原因:subscript:subrange延伸超过String end是因为一些捕获组可能在不匹配时返回NSRange(location: NSNotFound, length: 0)。 (NSNotFound是一个巨大的国际。)

当使用?|将捕获组包含在某些可选模式中时会发生这种情况。

我们可以在将Range(nsRange, in: str)转换为NSRange时使用Range<String.Index>,在这种情况下返回nil(不是崩溃!)。

所以,你可以这样写:

extension String {
    func capturedGroups(withRegex regex: NSRegularExpression) -> [String] {
        guard let match = regex.firstMatch(in: self, options: [], range: NSRange(0..<utf16.count)) else {
            return []
        }

        let lastRangeIndex = match.numberOfRanges - 1
        guard lastRangeIndex >= 1 else { return [] }

        return (1...lastRangeIndex).compactMap {Range(match.range(at: $0), in: self)}
            .map {String(self[$0])}
    }
}

使用上面的扩展,您可以获得以下输出:

let response1 = "Tambah saldo via transfer bank BCA PT.BARRYPRIMA CORP . No Rek:427.123.444 . Jumlah transfer Rp.200864."
let response2 = "Tambah saldo via transfer online Bersama BARRYPRIMA CORP . No Rek:123456. Jumlah transfer Rp.200864."
let response3 = "Tambah saldo via transfer bank Mandiri BARRYPRIMA . No Rek:43512343598347. Jumlah transfer Rp.200864."
let response4 = "Tambah saldo via merchant Tito ."
let response5 = "Tambah saldo via merchant Bagaskara putra."
[response1, response2, response3, response4, response5].forEach { str in
    print(str.capturedGroups(withRegex: regex))
}

输出:

["transfer bank", "BCA", "PT.BARRYPRIMA CORP", "427.123.444", "200864"]
["transfer online", "Bersama", "BARRYPRIMA CORP", "123456", "200864"]
["transfer bank", "Mandiri", "BARRYPRIMA", "43512343598347", "200864"]
["merchant", "Tito"]
["merchant", "Bagaskara putra"]
© www.soinside.com 2019 - 2024. All rights reserved.