class PhoneNumber { static final RegExp _nonNumeric = RegExp(r'[^0-9]+'); static final RegExp _letters = RegExp('[a-z]'); static final RegExp _punctuations = RegExp('[@:!?\$%^&*_`~,;]'); String clean(String input) { _checkForLetters(input); _checkForPunctuations(input); String cleaned = _removeNonNumeric(input); _validateLength(cleaned); _validateAreaCode(cleaned); _validateExchangeCode(cleaned); return (cleaned.length == 11) ? cleaned = cleaned.replaceFirst('1', '') : cleaned; } void _checkForLetters(String input) { if (input.toLowerCase().contains(_letters)) throw FormatException('letters not permitted'); } void _checkForPunctuations(String input) { if (input.toLowerCase().contains(_punctuations)) throw FormatException('punctuations not permitted'); } String _removeNonNumeric(String input) { return input.replaceAll(_nonNumeric, ''); } void _validateLength(String number) { if (number.length < 10) throw FormatException('must not be fewer than 10 digits'); if (number.length > 11) throw FormatException('must not be greater than 11 digits'); if (number.length == 11 && number[0] != '1') throw FormatException('11 digits must start with 1'); } void _validateAreaCode(String number) { if (number.length == 10 && number[0] == '0' || number.length == 11 && number[1] == '0') throw FormatException('area code cannot start with zero'); if (number.length == 10 && number[0] == '1' || number.length == 11 && number[1] == '1') throw FormatException('area code cannot start with one'); } void _validateExchangeCode(String number) { if (number.length == 10 && number[3] == '0' || number.length == 11 && number[4] == '0') throw FormatException('exchange code cannot start with zero'); if (number.length == 10 && number[3] == '1' || number.length == 11 && number[4] == '1') throw FormatException('exchange code cannot start with one'); } }