본문 바로가기
Data Science/SQL

[SQL/오답] 이메일 형식 검증, 정규표현식 수량자의 정밀도 제어 (LeetCode3436 Easy)

by 에르모사 쩐뉴 2026. 2. 16.

 

1. Problem

사용자 데이터베이스에서 유효한 이메일 주소만 추출해야 한다. 유효성 기준은 네 가지다.

  1. @ 심볼이 정확히 하나 포함될 것
  2. .com으로 끝날 것
  3. @ 앞부분은 영문자, 숫자, 언더바(_)만 허용할 것
  4. @와 .com 사이의 도메인 네임은 오직 영문자로만 구성될 것

단순히 패턴을 포함하는 것이 아니라, 시작(^)과 끝($)을 명확히 정의하여 전체 문자열의 형식을 강제하는 것이 핵심이다.

2. Solution

각 구간별 제약 조건을 정규표현식으로 세분화하여 설계한다.

  • 아이디 구간(^[a-zA-Z0-9_]+): 문자열 시작부터 @ 전까지 문자, 숫자, 언더바가 최소 1글자 이상(+) 있어야 한다.
  • 도메인 구간(@[a-zA-Z]+): @ 뒤에 영문 도메인 네임이 최소 1글자 이상(+) 이어져야 한다.
  • 마무리(\\.com$): 반드시 .com으로 끝나야 하며, 예약어인 마침표(.)를 일반 문자로 처리하기 위해 이스케이프(\\)를 사용한다.

3. Takeaway (Debug & Insights)

작성 과정에서 발생한 수량자 선택의 오류를 통해 패턴 매칭의 정밀도를 높이는 법을 배운다.

  • *(0개 이상) vs +(1개 이상)의 차이: 처음에 사용한 *은 해당 패턴이 없어도 통과시킨다. 이 경우 @example.com처럼 아이디가 없는 잘못된 이메일도 유효하다고 판단하게 된다. 최소 1글자 이상을 보장하는 +를 사용하는 것이 데이터 무결성 측면에서 안전하다.
  • 도메인 길이 제한: [a-zA-Z] 뒤에 수량자를 생략하면 딱 한 글자의 도메인만 인식한다. 실무 환경의 다양한 도메인 길이를 수용하기 위해 반드시 수량자를 붙여야 한다.
  • 확장성 고려: 면접관이 확장자 추가(예: .net, .org)를 요구한다면 \\.(com|net|org)$와 같이 그룹화(())와 파이프(|) 기호를 사용하여 대응할 수 있다.

https://leetcode.com/problems/find-valid-emails/description/

 

Find Valid Emails - LeetCode

Can you solve this real interview question? Find Valid Emails - Table: Users +-----------------+---------+ | Column Name | Type | +-----------------+---------+ | user_id | int | | email | varchar | +-----------------+---------+ (user_id) is the unique key

leetcode.com

 

Table: Users

+-----------------+---------+
| Column Name     | Type    |
+-----------------+---------+
| user_id         | int     |
| email           | varchar |
+-----------------+---------+
(user_id) is the unique key for this table.
Each row contains a user''s unique ID and email address.
Write a solution to find all the valid email addresses. A valid email address meets the following criteria:

It contains exactly one @ symbol.
It ends with .com.
The part before the @ symbol contains only alphanumeric characters and underscores.
The part after the @ symbol and before .com contains a domain name that contains only letters.
Return the result table ordered by user_id in ascending order.

 

Example:

Input:

Users table:

+---------+---------------------+
| user_id | email               |
+---------+---------------------+
| 1       | alice@example.com   |
| 2       | bob_at_example.com  |
| 3       | charlie@example.net |
| 4       | david@domain.com    |
| 5       | eve@invalid         |
+---------+---------------------+
Output:

+---------+-------------------+
| user_id | email             |
+---------+-------------------+
| 1       | alice@example.com |
| 4       | david@domain.com  |
+---------+-------------------+
Explanation:

alice@example.com is valid because it contains one @, alice is alphanumeric, and example.com starts with a letter and ends with .com.
bob_at_example.com is invalid because it contains an underscore instead of an @.
charlie@example.net is invalid because the domain does not end with .com.
david@domain.com is valid because it meets all criteria.
eve@invalid is invalid because the domain does not end with .com.
Result table is ordered by user_id in ascending order.

 

 

 

1. 정답 쿼리  

SELECT user_id, email
FROM Users 
WHERE email REGEXP '^[a-zA-Z0-9_]+@[a-zA-Z]+\\.com$' 
ORDER BY user_id ASC;

🎯 왜 이렇게 설계해야 할까요? 

구간 정규식 설명
ID 부분 ^[a-zA-Z0-9_]+ 문장의 시작(^)부터 @ 전까지 **문자/숫자/_**가 1개 이상(+) 있어야 함
구분자 @ 정확히 이 위치에 @가 있어야 함
도메인 [a-zA-Z]+ @와 .com 사이에는 오직 알파벳만 1개 이상(+) 올 수 있음
마무리 \\.com$ 반드시 .com으로 끝나야 함 (.은 정규식 기호이므로 \\로 무력화)

 

2. 나의 오답

SELECT user_id, email
FROM Users
WHERE email REGEXP '^[a-zA-Z0-9_]*@[a-zA-Z]\\.com$'
ORDER BY user_id ASC;

 

작성하신 패턴 ^[a-zA-Z0-9_]*@[a-zA-Z]\\.com$을 과학적으로 뜯어보고 교정해 드릴게요.


🔍 사용자님 정규식의 문제점 (Debug)

  1. [a-zA-Z0-9_]*: *은 0개 이상을 의미합니다. 즉, @example.com처럼 앞부분이 아예 없어도 통과됩니다. 보통 아이디는 1글자 이상이어야 하므로 +가 더 적절합니다.
  2. [a-zA-Z]: 이 부분은 딱 한 글자의 알파벳만 찾습니다. example 같은 여러 글자의 도메인을 잡으려면 여기에도 +가 필요합니다.

1. 출제자의 의도 (Why?)

  • 패턴 매칭의 정밀도: 단순히 @가 있는지를 보는 게 아니라, @ 앞뒤의 서로 다른 제약 조건을 정확히 분리해서 적용할 수 있는가?
  • 특수 문자 처리 능력: 정규식에서 예약어로 쓰이는 마침표(.)를 일반 문자로 처리하기 위해 **이스케이프(\.)**를 적절히 사용하는가?
  • 경계 조건(Boundary) 설정: 문자열의 처음(^)과 끝($)을 명시하여, 중간에 유효한 패턴이 섞여 있는 '잘못된 이메일'을 걸러낼 수 있는가?

2. 면접에서 나올 수 있는 질문 (예상 질문)

  • Q1. "작성하신 정규식에서 + 대신 *을 쓰면 어떤 문제가 발생할까요?"
    • 의도: 수량자(Quantifier)의 차이를 정확히 아는지 묻습니다.
    • 답변: "*은 0개 이상을 의미하므로 아이디나 도메인 네임이 비어 있는 @.com 같은 데이터도 유효하다고 판단하게 됩니다. 최소 1글자 이상을 보장하려면 +를 써야 합니다."
  • Q2. "만약 이메일 서비스가 .com뿐만 아니라 .net, .org까지 확장된다면 쿼리를 어떻게 수정하시겠습니까?"
    • 의도: 코드의 확장성과 그룹화(()) 능력을 봅니다.
    • 답변: "마지막 부분을 \.(com|net|org)$와 같이 그룹화와 파이프(|) 기호를 사용하여 여러 확장자를 동시에 수용하도록 수정하겠습니다."
  • Q3. "정규식은 편리하지만 성능 이슈가 있을 수 있습니다. 수백만 건의 이메일을 검사할 때 성능을 높이는 방법이 있을까요?"
    • 의도: 대용량 데이터 처리 경험을 봅니다.
    • 답변: "정규식은 CPU 부하가 높으므로, 가급적 인덱스를 탈 수 있는 LIKE 'a%' 같은 조건으로 1차 필터링을 한 뒤 정규식을 적용하거나, 데이터가 입력되는 시점에(Application Level) 미리 검증하여 DB에는 유효한 데이터만 저장하는 것이 효율적입니다."

3. 구직자가 던지면 좋은 '역질문'

  • "사내에서는 이메일 형식을 DB 정규식으로 관리하시나요, 아니면 별도의 Validator 라이브러리나 스키마 제약 조건(Check Constraint)을 활용하시나요?"
    • 효과: 시스템 전체의 아키텍처와 데이터 정제(Cleaning) 프로세스에 관심이 있음을 보여줍니다.
  • "이메일 도메인 유효성을 판단할 때, 패턴 매칭 외에 실제로 존재하는 도메인인지 확인하는 절차도 배치(Batch) 작업 등에 포함되어 있나요?"
    • 효과: 실제 비즈니스 운영에서 발생할 수 있는 '허수 데이터'에 대한 고민을 보여줍니다.

🎯 실무 지향적 로직 설계 접근법

정규식 문제를 풀 때는 항상 "나누어 정복하라(Divide and Conquer)" 전략을 쓰세요.

  1. 아이디 구간: [a-zA-Z0-9_]+ (문자, 숫자, 언더바)
  2. 구분자: @
  3. 도메인 구간: [a-zA-Z]+ (오직 알파벳)
  4. 마무리: \.com$ (반드시 .com으로 종료)

이 네 덩어리를 각각 설계한 뒤 하나로 합치는 습관을 들이면, 아무리 복잡한 정규식 문제도 논리적으로 풀어낼 수 있습니다.