Regex: 보이는 것보다 덜 무서워
정규 표현식은 읽을 수 없다는 평판이 있어. 그럴 필요 없어.
문서에서 모든 이메일 주소를 찾아야 해. 또는 전화번호를 검증. 또는 엉망인 텍스트에서 날짜를 추출.
누가 "regex 써"라고 해. 문법을 구글하고, ^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$ 같은 걸 찾고, 즉시 탭을 닫아.
정규 표현식이 위협적으로 보이는 건 사람들이 명확함 대신 영리하게 쓰기 때문이야. 고쳐보자.
리터럴 매칭으로 시작
Regex는 패턴을 찾아. 가장 간단한 패턴은 리터럴 텍스트야.
cat은 "The cat sat."에서 "cat"을 매치해. 특별한 거 없어.
http는 어떤 URL에서든 "http"를 매치해. 여전히 간단해.
와일드카드를 점진적으로 추가
.는 어떤 단일 문자든 매치해. c.t는 "cat", "cot", "cut"을 매치해.
*는 "이전 것의 0개 이상"을 의미해. ca*t는 "ct", "cat", "caat", "caaaaaat"을 매치해.
+는 "1개 이상"을 의미해. ca+t는 "cat"과 "caat"을 매치하지만 "ct"는 안 해.
?는 "0개 또는 1개"를 의미해. colou?r은 "color"와 "colour" 둘 다 매치해.
문자 클래스가 친구야
[aeiou]는 모든 모음을 매치해. [0-9]는 모든 숫자. [A-Za-z]는 모든 문자.
\d는 [0-9]의 축약이야. \w는 단어 문자 (문자, 숫자, 밑줄)를 매치해. \s는 공백을 매치해.
이 빌딩 블록들이 대부분의 실제 패턴을 다뤄.
앵커가 위치를 제어해
^는 "줄 시작"을 의미해. $는 "줄 끝".
^Hello는 "Hello world"를 매치하지만 "Say Hello"는 안 해.
world$는 "Hello world"를 매치하지만 "world peace"는 안 해.
그룹이 부분을 캡처해
괄호는 것들을 그룹화해. 나중 사용을 위해 캡처도 해.
(\d{3})-(\d{4})는 "555-1234"를 매치하고 "555"와 "1234"를 따로 캡처해.
이게 패턴 매치에서 특정 데이터를 추출하는 법이야.
실제 예제, 설명된
이메일 (단순화):
[\w.-]+@[\w.-]+\.\w+
번역: 단어 문자/점/하이픈, 그다음 @, 그다음 더 같은 거, 그다음 점, 그다음 단어 문자.
전화번호:
\d{3}[-.\s]?\d{3}[-.\s]?\d{4}
번역: 3자리 숫자, 선택적 구분자, 3자리 숫자, 선택적 구분자, 4자리 숫자. "555-123-4567", "555.123.4567", "5551234567" 매치.
날짜 (MM/DD/YYYY):
\d{2}/\d{2}/\d{4}
번역: 2자리 숫자, 슬래시, 2자리 숫자, 슬래시, 4자리 숫자.
흔한 실수
특수 문자 이스케이프 잊기. .는 regex에서 "어떤 문자"를 의미해. 리터럴 점을 매치하려면 \. 써.
너무 탐욕적이기. .*는 가능한 많이 매치해. HTML 태그는 <b>bold</b>에서 <.*>가 그냥 <b>가 아니라 전체를 매치해. 비탐욕적 매칭엔 <.*?> 써.
과도하게 복잡하게. 이메일을 진짜로 검증해야 하면 라이브러리 써. "올바른" 이메일 regex는 수백 자 길어.
Regex를 쓰지 말아야 할 때
HTML이나 JSON 파싱. 적절한 파서 써.
복잡한 검증 로직. 코드가 종종 하나의 거대한 패턴보다 명확해.
문자열 메서드가 작동할 때. "hello".startsWith("he")가 /^he/보다 명확해.
Regex는 도구야. 어떤 도구처럼 특정 작업엔 좋고 다른 것엔 어색해. 간단하게 시작하고, 만들면서 테스트하고, 영리해지려 하지 마. 읽기 쉬운 regex가 인상적인 regex보다 나아.