약 2주 전쯤에 코딩테스트를 하다가 문자열 다루기 기본이라는 문제를 풀게 됐다. 지금 보면 충분히 다른 방식으로도 풀 수 있는 문제였지만, 당시에는 왜인지 모르게 문제가 잘 안 풀려서 질문하기에 가봤더니 정규식을 사용해 보라는 말이 있었다. 그래서 그때 처음으로 정규식을 써봤었다. 그런데 그때는 단순히 문제를 풀기 위해 사용했던 거라, 어떤 것이 뭘 의미하는 것인지도 모르고 정규식 관련 함수도 몰랐었다. 그래서 이 글에서 한 번 정리해 보려고 한다.
정규 표현식(regular expression)은 문자를 표현하는 일종의 공식으로, 특정 규칙이 있는 문자열 집합을 추출할 때 자주 사용되는 기법이다. 주로 프로그래밍에서 문자열의 검색과 치환을 위한 용도로 쓰이고 있다. 간단하게 정규식이라고도 부르며, 보통 RegEx 혹은 RegExp라 많이 쓴다.
메타문자는 문자를 설명하기 위한 문자로, 문자의 구성을 설명하기 위해 원래의 의미가 아닌 다른 의미로 쓰이는 문자를 말한다.
정규표현식에서는 아래와 같은 메타문자를 사용한다.
. (Dot): 아무 문자 한 개를 의미 (줄 바꿈 문자 제외)a.b → a와 b 사이에 아무 문자 한 개가 있는 문자열 매칭 (acb, a1b 등)
^ (Caret): 문자열의 시작을 나타냄^abc → 문자열이 abc로 시작하는 경우 매칭 (abc123, abc 등)
$ (Dollar): 문자열의 끝을 나타냄abc$ → 문자열이 abc로 끝나는 경우 매칭 (123abc, abc 등)
* (Asterisk): 바로 앞에 있는 패턴이 0번 이상 반복됨을 의미a* → a가 0번 이상 반복된 문자열 매칭 ("" ,a, aaa 등)
+ (Plus): 바로 앞에 있는 패턴이 1번 이상 반복됨을 의미a+ → a가 1번 이상 반복된 문자열 매칭 (a, aa, aaa 등)
? (Question Mark): 바로 앞에 있는 패턴이 0번 또는 1번 존재함을 의미a? → a가 없거나 1번 있는 경우 매칭 ("", a)
{} (Curly Braces): 반복 횟수를 지정a{2} → a가 정확히 2번 반복된 문자열 매칭 (aa)
a{2,4} → a가 2~4번 반복된 문자열 매칭 (aa, aaa, aaaa)
[abc] → a, b, c 중 하나와 매칭
[0-9] → 숫자 0부터 9까지 중 하나와 매칭
\. → 메타문자 .을 문자 .으로 매칭
\d → 숫자와 매칭 ([0-9]와 동일)
a|b → a 또는 b와 매칭
(abc) → abc를 하나의 그룹으로 캡처
a(b|c) → ab 또는 ac와 매칭
// 이메일 주소 확인
const reg = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/
// 최소 8자리 이상 영문 대소문자, 숫자, 특수문자가 각각 1개 이상
const reg = /^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$ %^&*-]).{8,}$/;
// 년월일 (yyyy-mm-dd) 체크
const reg = /^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/;
// 웹사이트 링크인지 체크
const reg = <a\s+(?:[^>]*)href=\"((?:https:\/\/|http:\/\/)(?:.*?))">(?:.*?)<\/a>;
문자열이 정규식에 일치하는지 Boolean 값을 반환한다.
정규식.test(문자열)
const regex = /hello/i;
console.log(regex.test("Hello world")); // true
console.log(regex.test("Hi there")); // false
일치하는 문자열을 배열(Array)로 반환한다. 없으면 null을 반환한다.
문자열.match(정규식)
const str = "Hello hello world";
const regex = /hello/gi;
console.log(str.match(regex)); // ['Hello', 'hello']
일치하는 문자열을 새로운 문자열로 대체하고, 대체된 결과를 문자열(String)로 반환한다.
문자열.replace(정규식, 대체문자)
const str = "Hello world";
console.log(str.replace(/world/, "JavaScript")); // "Hello JavaScript"
오늘은 코딩테스트를 풀다가 알게 된 정규 표현식을 공부하고 정리해봤다. 느낀 점을 솔직히 말해보면, 관련 메서드는 유용하게 잘 사용할 것 같지만, 정규식을 그때그때 필요에 맞게 만드는 것은 좀 어려울 것 같다...