1. Problem
웹사이트 가입자 중 유효한 이메일 형식을 가진 사용자를 필터링해야 한다.
- Prefix 조건: 반드시 문자로 시작해야 하며, 이후에는 문자, 숫자, 언더바(_), 마침표(.), 대시(-)만 허용된다.
- Domain 조건: 반드시 @leetcode.com이어야 한다. 정규식의 문법적 정확도뿐만 아니라, 도메인의 대소문자 정합성까지 검증해야 하는 문제이다.
2. Solution: REGEXP와 BINARY의 결합
문자열 패턴은 REGEXP로 잡고, 엄격한 대소문자 비교는 LIKE BINARY에 위임한다.
3. Takeaway: 정규식 설계와 SQL의 특성
- 정규식의 정밀 설계 (^와 $): 시작(^)과 끝($) 앵커를 명시하여 이메일 앞뒤에 원치 않는 공백이나 쓰레기 데이터가 붙는 것을 방지한다. 특히 .은 정규식에서 '모든 문자'를 의미하므로, 실제 마침표를 의미하기 위해 이스케이프(\\.) 처리를 한 점이 객관적으로 정확하다.
- 대소문자 민감도의 함정: MySQL의 REGEXP는 기본 설정(Collation)에 따라 대소문자를 구분하지 않는 경우가 많다. 따라서 @LEETCODE.com과 같은 데이터를 걸러내기 위해 **LIKE BINARY**를 추가한 것은 매우 안전한 방어적 프로그래밍 기법이다.
- Prefix 규칙의 구현: [a-zA-Z](시작 문자)와 [a-zA-Z0-9_.-]*(이후 허용 문자들)를 분리하여 "반드시 문자로 시작해야 한다"는 까다로운 조건을 완벽히 구현했다.
https://leetcode.com/problems/find-users-with-valid-e-mails/description/
Table: Users
+---------------+---------+
| Column Name | Type |
+---------------+---------+
| user_id | int |
| name | varchar |
| mail | varchar |
+---------------+---------+
user_id is the primary key (column with unique values) for this table.
This table contains information of the users signed up in a website. Some e-mails are invalid.
Write a solution to find the users who have valid emails.
A valid e-mail has a prefix name and a domain where:
The prefix name is a string that may contain letters (upper or lower case), digits, underscore '_', period '.', and/or dash '-'. The prefix name must start with a letter.
The domain is '@leetcode.com'.
Return the result table in any order.
The result format is in the following example.
Example 1:
Input:
Users table:
+---------+-----------+-------------------------+
| user_id | name | mail |
+---------+-----------+-------------------------+
| 1 | Winston | winston@leetcode.com |
| 2 | Jonathan | jonathanisgreat |
| 3 | Annabelle | bella-@leetcode.com |
| 4 | Sally | sally.come@leetcode.com |
| 5 | Marwan | quarz#2020@leetcode.com |
| 6 | David | david69@gmail.com |
| 7 | Shapiro | .shapo@leetcode.com |
+---------+-----------+-------------------------+
Output:
+---------+-----------+-------------------------+
| user_id | name | mail |
+---------+-----------+-------------------------+
| 1 | Winston | winston@leetcode.com |
| 3 | Annabelle | bella-@leetcode.com |
| 4 | Sally | sally.come@leetcode.com |
+---------+-----------+-------------------------+
Explanation:
The mail of user 2 does not have a domain.
The mail of user 5 has the # sign which is not allowed.
The mail of user 6 does not have the leetcode domain.
The mail of user 7 starts with a period.
1. 답안 쿼리
SELECT
user_id,
name,
mail
FROM
users
WHERE
mail REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*@leetcode\\.com$'
AND mail LIKE BINARY '%@leetcode.com';
| 조건 | 의미 |
| REGEXP '^[a-zA-Z][a-zA-Z0-9_.-]*@leetcode\\.com$' | prefix 규칙 체크 |
| LIKE BINARY '%@leetcode.com' | domain이 정확히 소문자 leetcode.com인지 체크 |
🔍 정규식 해부
^
- 문자열 시작
- 앞에 쓰레기 문자 못 오게 차단
[a-zA-Z]
- 반드시 문자로 시작
- 문제 조건: prefix must start with a letter ✅
[a-zA-Z0-9_.-]*
- 이후에는
- 문자
- 숫자
- _ . -
- 0개 이상 허용
- bella-, sally.come 전부 OK
@leetcode\\.com
- @leetcode.com 정확히 매칭
- SQL 문자열 안이라서 \ → \\ 필요 ❗
$
- 문자열 끝
- 뒤에 다른 도메인 / 문자 붙는 거 차단
REGEXP만 쓰면 대소문자 구분이 안 됨
→ 즉, @LeetCode.com, @LEETCODE.COM 같은 것도 통과될 수 있음
하지만 문제는 도메인이 정확히 @leetcode.com이어야 함
→ 소문자 고정
그래서 추가로 LIKE BINARY를 넣어서 대소문자까지 엄격히 체크한 것이 정답이 되는 거야.
mail LIKE BINARY '%@leetcode.com'
이 조건이 추가되면,
- @LeetCode.com → FAIL
- @leetcode.com → PASS