asNumber method

  1. @override
num? asNumber(
  1. String term
)

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;
}