I'm using swift to learn regex. I don't know why the wholeMatch
method return nil, but the matches
is correct.
var statement =
"""
CREDIT 04062020 PayPal transfer $4.99
CREDIT 04032020 Payroll $69.73
DEBIT 04022020 ACH transfer $38.25
DEBIT 03242020 IRS tax payment $52249.98
"""
enum TransactionKind: String {
case credit = "CREDIT"
case debit = "DEBIT"
}
struct Date {
var month, day, year: Int
init?(mmddyyyy: String) {
self.month = 1
self.day = 1
self.year = 2022
}
}
struct Amount {
var valueTimes100: Int = 0
init?(twoDecimalPlaces text: Substring) {
self.valueTimes100 = Int(100 * (Float(text) ?? 0))
}
}
let statementPattern = Regex {
TryCapture {
ChoiceOf {
"CREDIT"
"DEBIT"
}
} transform: {
TransactionKind(rawValue: String($0))
}
OneOrMore(.whitespace)
TryCapture {
Repeat(.digit, count: 2)
Repeat(.digit, count: 2)
Repeat(.digit, count: 4)
} transform: { Date(mmddyyyy: String($0)) }
OneOrMore(.whitespace)
Capture {
OneOrMore(CharacterClass(.word, .whitespace))
CharacterClass.word
} transform: {
String($0)
}
OneOrMore(.whitespace)
"$"
TryCapture {
OneOrMore(.digit)
"."
Repeat(.digit, count: 2)
} transform: {
Amount(twoDecimalPlaces: $0)
}
}
let results = try? statementPattern.wholeMatch(in: statement)
print(results) // print nil
for match in statement.matches(of: statementPattern) {
let (line, kind, date, description, amount) = match.output
print(description) // can correct print
}
CodePudding user response:
wholeMatch
means that the pattern must match the entire string.
It's the equivalent of a literal pattern which starts with ^
and ends with $
.
You can prove it by removing three lines in the string.