即时通讯使用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:致命错误:下标:子范围扩展到字符串结束
首先,您需要修改正则表达式模式,以获得您描述的预期捕获。
(?:...)
抑制一些捕获([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"]