How to Validate Phone Number
Quick Answer: Validate Phone Number in Bash
To validate US phone numbers, use: [[ "$phone" =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]] for format 123-456-7890 or [[ "$phone" =~ ^[0-9]{10}$ ]] for 10 digits only. Different patterns work for different formats.
Quick Comparison: Phone Validation Methods
| Format | Pattern | Strictness | Use Case |
|---|---|---|---|
| 10 digits | ^[0-9]{10}$ | Strict | US/Canada |
| dashes | ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ | Formatted | Formatted input |
| flexible | ^[0-9+\-\s()]{10,}$ | Loose | User-friendly |
| intl prefix | ^\\+[0-9]{1,3}-?[0-9]{6,14}$ | International | Global numbers |
Bottom line: Choose pattern based on expected format; simple 10-digit for basic validation.
Validate phone numbers in Bash using regex patterns. This tutorial covers common phone number formats and practical validation methods.
Phone Number Formats
Phone numbers vary by region. The most common formats are:
- US/Canada:
(123) 456-7890or123-456-7890or1234567890 - International:
+1-123-456-7890 - Simple:
123 456 7890or1234567890
Method 1: Basic Validation Pattern
#!/bin/bash
phone="555-123-4567"
# US format: XXX-XXX-XXXX
if [[ $phone =~ ^[0-9]{3}-[0-9]{3}-[0-9]{4}$ ]]; then
echo "Valid phone number"
else
echo "Invalid format"
fi
Output:
Valid phone number
Validate Multiple Formats
#!/bin/bash
validate_phone() {
local phone="$1"
# Match: (123) 456-7890 or 123-456-7890 or 1234567890
if [[ $phone =~ ^(\([0-9]{3}\)|[0-9]{3}[-.]?)?[0-9]{3}[-.]?[0-9]{4}$ ]]; then
return 0
else
return 1
fi
}
# Test cases
validate_phone "555-123-4567" && echo "Valid" || echo "Invalid"
validate_phone "(555) 123-4567" && echo "Valid" || echo "Invalid"
validate_phone "5551234567" && echo "Valid" || echo "Invalid"
validate_phone "555.123.4567" && echo "Valid" || echo "Invalid"
validate_phone "invalid" && echo "Valid" || echo "Invalid"
Output:
Valid
Valid
Valid
Valid
Invalid
International Format Validation
#!/bin/bash
validate_intl_phone() {
local phone="$1"
# Match: +1-123-456-7890 or +44-20-1234-5678
if [[ $phone =~ ^\+[0-9]{1,3}-[0-9]{2,4}-[0-9]{3,4}-[0-9]{4}$ ]]; then
return 0
else
return 1
fi
}
# Test
validate_intl_phone "+1-555-123-4567" && echo "Valid" || echo "Invalid"
validate_intl_phone "+44-20-1234-5678" && echo "Valid" || echo "Invalid"
Output:
Valid
Valid
Remove Non-Digits and Validate
#!/bin/bash
validate_phone_digits() {
local phone="$1"
# Remove all non-digits
local digits_only="${phone//[^0-9]/}"
# Must be 10 digits (US format)
if [[ $digits_only =~ ^[0-9]{10}$ ]]; then
echo "Valid: $digits_only"
else
echo "Invalid: Expected 10 digits, got ${#digits_only}"
fi
}
validate_phone_digits "(555) 123-4567"
validate_phone_digits "555.123.4567"
validate_phone_digits "12345"
Output:
Valid: 5551234567
Valid: 5551234567
Invalid: Expected 10 digits, got 5
Practical Example: Phone List Validator
#!/bin/bash
# File: validate_phones.sh
validate_phone() {
local phone="$1"
# US phone: flexible format
if [[ $phone =~ ^(\+?1[-.]?)?(\()?[0-9]{3}(\))?[-. ]?[0-9]{3}[-. ]?[0-9]{4}$ ]]; then
return 0
else
return 1
fi
}
input_file="$1"
if [ ! -f "$input_file" ]; then
echo "ERROR: File not found"
exit 1
fi
valid_count=0
invalid_count=0
while IFS= read -r phone; do
# Skip empty lines
[ -z "$phone" ] && continue
if validate_phone "$phone"; then
echo "✓ VALID: $phone"
((valid_count++))
else
echo "✗ INVALID: $phone"
((invalid_count++))
fi
done < "$input_file"
echo ""
echo "Summary: $valid_count valid, $invalid_count invalid"
Test file (phones.txt):
555-123-4567
(555) 123-4567
5551234567
555.123.4567
invalid123
+1-555-123-4567
Run:
$ chmod +x validate_phones.sh
$ ./validate_phones.sh phones.txt
Output:
✓ VALID: 555-123-4567
✓ VALID: (555) 123-4567
✓ VALID: 5551234567
✓ VALID: 555.123.4567
✗ INVALID: invalid123
✓ VALID: +1-555-123-4567
Summary: 5 valid, 1 invalid
Strict North American Format
#!/bin/bash
validate_na_phone() {
local phone="$1"
# Strict: exactly 10 digits in any standard format
local digits="${phone//[^0-9]/}"
if [[ $digits =~ ^[0-9]{10}$ ]]; then
# Format for display
local area="${digits:0:3}"
local exchange="${digits:3:3}"
local subscriber="${digits:6:4}"
echo "($area) $exchange-$subscriber"
return 0
else
return 1
fi
}
# Test
result=$(validate_na_phone "555-123-4567")
if [ $? -eq 0 ]; then
echo "Formatted: $result"
fi
Output:
Formatted: (555) 123-4567
Common Mistakes
- Forgetting to escape parentheses in regex - they need escaping
- Not handling country code variations - +1, +44, etc.
- Assuming single format - support multiple separators
- No length validation - check total digits first
- Case sensitivity - not an issue, but pattern inconsistency is
Key Points
- Use
[[ $var =~ pattern ]]for regex matching - Phone formats vary greatly by region
- Extract digits with
${phone//[^0-9]/}for easy validation - Always test with real-world phone numbers
- Provide helpful error messages to users
Summary
Phone validation requires flexible regex patterns since formats vary. Start with digit extraction for simplicity, then add format-specific patterns as needed. Always validate on the server side, even if you validate client-side.