Valid Phone Numbers

easy string regex bash

Problem

Print all valid phone numbers from file.txt. A valid phone number must look like (xxx) xxx-xxxx or xxx-xxx-xxxx where x is a digit. Each line of the file contains a single string. Canonical bash: grep -E '^([0-9]{3}-|\(([0-9]{3})\) )[0-9]{3}-[0-9]{4}$' file.txt.

Input987-123-4567\n123 456 7890\n(001) 345-0000
Output987-123-4567\n(001) 345-0000
Line 2 is rejected because it uses spaces instead of dashes.

# Bash one-liner:
# grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
import re

PHONE = re.compile(r'^(\d{3}-|\(\d{3}\) )\d{3}-\d{4}$')

def valid_phone_numbers(lines):
    return [ln for ln in lines if PHONE.match(ln)]
// Bash one-liner:
// grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
const PHONE = /^(\d{3}-|\(\d{3}\) )\d{3}-\d{4}$/;

function validPhoneNumbers(lines) {
  return lines.filter(ln => PHONE.test(ln));
}
// Bash one-liner:
// grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
class Solution {
    static final Pattern PHONE = Pattern.compile(
        "^(\\d{3}-|\\(\\d{3}\\) )\\d{3}-\\d{4}$"
    );
    public List<String> validPhoneNumbers(List<String> lines) {
        List<String> out = new ArrayList<>();
        for (String ln : lines) if (PHONE.matcher(ln).matches()) out.add(ln);
        return out;
    }
}
// Bash one-liner:
// grep -E '^([0-9]{3}-|\([0-9]{3}\) )[0-9]{3}-[0-9]{4}$' file.txt
#include <regex>
static const regex PHONE("^(\\d{3}-|\\(\\d{3}\\) )\\d{3}-\\d{4}$");

vector<string> validPhoneNumbers(vector<string>& lines) {
    vector<string> out;
    for (auto& ln : lines) if (regex_match(ln, PHONE)) out.push_back(ln);
    return out;
}
Time: O(total chars) Space: O(matches)