quantityFromString method

double? quantityFromString()

Parses a quantity in which either '.' or ',' is the decimal separator.

  • A single separator is decimal, whatever the region uses: '1234,661' and '1234.661' → 1234.661, '1,500' → 1.5.
  • With both separators the last one is decimal, the other one groups thousands: '1.234,5' and '1,234.5' → 1234.5.
  • The same separator repeated groups thousands: '1.234.567' → 1234567. Any other repetition, like '1,5,3', is not a number.

Everything except digits, signs and separators is ignored: '1 234,5 kg' → 1234.5.

Implementation

double? quantityFromString() {
  final String text = replaceAll(RegExp(r'[^0-9.,+-]'), '');
  final List<String> parts = text.split(RegExp('[.,]'));
  if (parts.length == 1) return double.tryParse(text);

  // '1.234.567': the same separator repeated can only group thousands
  final bool hasBothSeparators = text.contains('.') && text.contains(',');
  if (parts.length > 2 && !hasBothSeparators) {
    final bool isThousands = RegExp(r'^[+-]?\d{1,3}([.,]\d{3})+$').hasMatch(text);
    return isThousands ? double.tryParse(parts.join()) : null;
  }

  // '1234,5' or '1.234,5': the last separator is the decimal one
  final String integerPart = parts.sublist(0, parts.length - 1).join();
  return double.tryParse('$integerPart.${parts.last}');
}