asNumber method
Attempts to parse the term to a number. Returns null if the term does not represent a number, amount or percentage
Implementation
@override
num? asNumber(String term) {
// remove commas, + signs and whitespace
// replace "percent" with "%"
term = term.replaceAll(r',\s\+', '').replaceAll('percent', '%');
// check for presence of leading dash, multiply by -1.0 if present.
var x =
(RegExp(r'(?<=^)-(?=\W\d|[A-Z]{3}|\d)').allMatches(term).length == 1)
? -1.0
: 1.0;
// remove all dashes
term = term.replaceAll(r'[\-]', '');
// if percent then divide by 100
x = (RegExp(r'(?<=\d)\s?%(?=\Z)').allMatches(term).length == 1)
? x / 100
: x;
// remove all "%" signs
term = term.replaceAll(r'[\%]', '');
// match all numbers where
// - preceded by the start of the string or
// - prececed by the start of the string AND a single non-word character or
// three/ upper-case letters; AND
// - AND followed by the end of the string
final numbers =
RegExp(r'(?<=^|[A-Z]{3}|\A\W)(\d|((?<=\d)[,.]{1}(?=\d)))+(?=$)')
.allMatches(term.normalizeWhitespace());
if (numbers.length != 1) {
return null;
}
final text = numbers.first[0];
final number = (text != null) ? num.tryParse(text) : null;
return number == null
? null
: term.endsWith('%')
? x * number / 100
: number * x;
}