정규표현식 톺아보기!
1.정규 표현식(Regular Expression)은 왜 사용할까?
정규 표현식은 문자열에 포함된 특정 문자 조합을 찾기 위해 사용되는 패턴이다. 복잡한 코드를 아주 간략하게 작성할 수 있다는 장점이 있지만 가독성이 떨어지고 코드 구현이 쉽지 않다는 단점도 갖고 있다. 이러한 단점에도 불구하고 우리가 정규표현식을 사용하는데는 굉장히 어려운 프로그램도 쉽게 해결할 수 있다는 장점이 가장 크게 작용하지 않을까 생각한다! 실무에서 정규 표현식을 가장 많이 사용하는 사례는 사용자가 입력한 이메일 정보가 이메일 형식에 맞는지, 전화번호가 전화번호 형식에 맞는지 등 사용자로부터 입력받은 데이터가 프로그램에서 받고자 하는 데이터 형식과 일치여부를 체크할 때라고 한다.
2. 정규식 ! 한 번 만들어보자!
정규식을 만드는 방법은 두 가지가 있다. 1) 슬래시
/
로 감싸는 패턴인 정규식 리터럴을 사용하는 방법
const regexp = /world/;
2) RegExp 객체의 생성자 함수를 사용하는 방법
const refexp = new RegExp("World");
생성자 함수를 사용하면 정규식이 실행 시점에 컴파일된다. 정규식 패턴이 변경될 수 있더나, 사용자 입력이나 데이터베이스 등 다른 출처로부터 오는 정보에 따라 정규식 패턴을 동적으로 적용해야 하는 경우는 생성자 함수를 사용하면 된다.
3. 정규식 함수 정리하기!
정규식에서 제공하는 내장함수를 이렇다.
함수설명exec정규식을 통해 찾고자하는 문자열 패턴을 찾고 배열을 반환한다.(대응되는 문자열을 찾지못하면 null
을 반환한다.)test대응되는 문자열이 있는지 검사하고 있으면 true, 없으면 false를 반환한다.match대응되는 문자열을 찾아 배열로 반환하는 String 객체 내장 함수이다. 대응되는 문자열이 없으면 null을 반환한다(exec함수와 동일한 기능을 한다.)search대응되는 문자열이 있는지 검사하고 대응되는 첫 번쨰 문자열의 인덱스를 반환한다. 대응되는 문자열이 없으면 -1을 반환한다.replace대응되는 문자열을 찾아 문자열로 치환하는 String 객체 내장 함수이다.split대응되는 문자열을 찾고 찾은 문자열을 기준으로 나누어서 배열로 반환하는 String 객체 내장 함수이다.
[예제] 실제로 해보기!
let str = "Hello World! world!";
const re = /World/;
console.log(re.test(str));
console.log(str.search(re));
4. 정규식 특수문자 정복하기!
\
문자 앞 백슬래시는 특수문자가 아닌 일반 문자로 인식하게 한다. 특수 문자 앞 백슬래시는 다음나오는 문자는 특별하지 않고 문자 그대로 해석되어야 한다는 뜻이다.^
입력의 시작부분에 대응된다. 즉 문자열의 시작을 의미한다$
입력의 끝 부분과 대응된다. 특수문자^
와는 반대이다.*
특수문자 앞의 표현식이 0회 이상 반복되는 부분과 대응된다.{0,}와 같은 의미이다. [ex]/bo/=> b를 포함하고 b다음에 오는 "o"가 0회 이상, o가 있을 수도 있고 없을 수도 있다. boom, A bird와는 대응 A goat와는 대응하지 않는다.+
특수문자 +앞의 표현식이 1회 이상 반복되는 부분과 대응된다. {1,}와 같은 의미이다.?
특수문자 ? 앞의 표현식이 0또는 1회 등장하는 부분과 대응된다. {0,1}와 같은 의미이다..
단일 문자에 대응 된다. [ex] /.n/ => an apple에서 an에 대응된다.(x)
괄호는 포획 괄호라 부른다. 괄호 안에 패턴 전체에 적용된다.(?:x)
여기서 괄호는 비포획 괄호라 부른다. 사용법은 (x)와 동일하지만 차이점은 대응되는 결과를 기억하지 않는 다는 것이다.x(?=y)x뒤에 y가 뒤따라오는 경우에만 대응된다. 이것을 lookahead라고 부른다. [ex] /₩d+(?=g)/ 는 숫자 뒤에 'g'가 뒤따라오는 경우에만 대응됩니다. an apple is 100g*의 100에 대응된다.x(?!y)
x 뒤에 'y가 없는 경우에만 대응됩니다. 이것을 negative lookahead라고 부른다.x(수직선,버티컬 바)
yx 또는 y에 대응된다. [ex] /greenired/ 는 문자열에 'green' 혹은 "red"가 포함되었는지에 대응된다. green apple의 green에 대응되고, 'red apple'의 red에도 대응된다.{n}앞 표현식이 n번 나타나는 부분에 대응된다. n은 반드시 양의 정수이다.{n,m}n과 m은 양의 정수이고n <= m
을 만족해야한다. 앞 표현식이 최소 n개 최대 m개가 나타나는 부분에 대응된다.[xyz]문자셋입니다. 하이픈(-)을 상용해서 문자의 범위를 지정할 수 있다.[^xyz]
부정 문자셋이다. 패턴에 포함된 문자가 없는지와 대응된다. 하이픈(-)을 사용해서 문자의 범위를 지정할 수 있다.[\b]
백스페이스에 대응된다. 백스페이스 문자에 대응시키려면 대활호를 사용해야한다.\b
문자열에 있는 단어의 경계, 즉 첫 문자와 종료 문자에 대응된다.\B
단어 경계가 아닌 부분에 대응된다.\d
숫자 문자에 대응된다. [ex] /\d/는 Cloud9에서 9에 대응된다.\D
숫자가 아닌 문자에 대응된다. [ex] /\d/는 Cloud9에서 C에 대응된다.\f
폼피드(U+000C) 문자에 대응된다.\n
줄 바꿈(U+OOOA) 문자에 대응된다.\r
엔터 키에 해당하는 문자에 대응된다.\s
하나의 공백 문자에 대응된다.\S
공백 문자가 아닌 문자에 대응된다.\t
탭(U+0009) 문자에 대응된다.\v
수직 탭(U+000B) 문자에 대응된다.\w
밑줄 문자를 포함한 숫자, 영문 문자에 대응된다.\W
밑줄 문자, 숫자, 영문 문자가 아닌 문자에 대응된다. [^A-Za-20-9_] 와 동일하다.
5.정규식 플래그
1) g
: 전역검색 - 대응되는 문자 전부 검색 2) i
: 대소문자 구분 없는 검색 3) m
: 다중 행 검색
6. 정규식 실제 사례에서 사용해보기!
핸드폰번호가 올바른 형식인지 체크하는 정규식을 만들어볼까요?
const regexp_mobile = /^(010)-\d{4}-\d{4}$/;
// 반드시 010으로 시작하고 그다은 하이픈(-) 숫자 4자리, 하이픈(-), 숫자 4자리가 차례대로 입력되어야 하는 형식의 정규식
console.log(regexp_mobile.test("010-1234-5678"))
console.log(regexp_mobile.test("010-1234-567"))
정리하기
정규식을 정리한 이유는 사실 코딩테스트를 공부하면서 문자열 관련 문제를 풀 때 편리하기 위해서가 컸다. 정규식을 사용하지 않고 문자열에 관한 문제를 풀려고 하니 식이 복잡해지고 적어야하는 코드가 너무 길어져 불편함을 느꼈다! 이번을 계기로 정리하게 되어 앞으로 자주 응용해서 써봐야겠다. 하지만 정규식 자체를 프로젝트 코드에서 필요한 부분이 아닌 곳에 남발하게 되면 코드의 가독성이 매우 떨어져 이 점은 경계하며 사용해야겠다. 특정 규칙이 존재하는 데이터 입력시에만 딱 알맞게 사용하는 것을 명심하자!