본문 바로가기
etc.

[그 때 알았더라면] 정규 표현식 빠르게 정리해보기 (TIL0917)

by 돈민찌 2021. 9. 19.
반응형

웹사이트를 개발하다보면, input 태그에서 사용자의 입력을 받을 때, 그 값이 내가 원하는 형식이 맞는지, 입력값을 받아오기 전에 확인해주는 과정이 필수가 된다. 예를 들면 이메일에 @ 이 들어가고 뒤에 도메인이 붙는지 라던가- 비밀번호 입력을 할 때 최소한의 보안을 위해 특수문자 사용을 필수로 한다던가 하는 부분 말이다. 각 사이트마다 이러한 규칙이 조금씩 다르기는 하지만, 어느정도의 표준안은 있기 때문에, 필요한 순간에 해당 내용을 구글링해서 가져다 써도 되지만, 이왕 하는 거 원리를 잘 알고 쓰는게 좋지 않을까 해서 정리를 해 둔다.

정규 표현식(正規表現式, 영어: regular expression, 간단히 regexp 또는 regex) 또는 정규식(正規式)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다.

 

정규 표현식은 알아두면 좋다. 각 프로그래밍 언어마다 가지고 있는 문법 때문에 약간의 차이는 있지만, 원리를 꿰뚫고 나면 그런 것은 바로 적응할 수 있고, 거의 모든 언어에서 사용 가능하다. 심지어는 마이크로소프트 워드/엑셀 등에서도 비슷한 기능을 지원한다. 배워둬서 절대 손해 볼 일 없는 필수적인 지식이다.

위에서 예를 들었던 형식 확인은 보통 validation이라고 부르는데, 이 뿐만 아니라, 특정 텍스트 뭉치에서 내가 원하는 데이터(전화번호, 이메일, URL, 주소 등)를 찾아내 추출하거나, IDE에서 replace 기능을 사용할 때에도 사용할 수 있다. 이번에 강의를 듣다가 회원가입 구현하는 부분에서 정규표현식을 사용했어서, 생각이 난 김에 정리를 해두려고 한다.

정규 표현식의 구성요소

정규표현식은 기본적으로 시작기호/ + 패턴 + 끝기호/ + (플래그) 형식으로 이뤄져있다. 패턴은 일반적으로 찾을 수 있는 복잡한 형식일 수도 있지만 단순하게 찾고자 하는 텍스트만 입력해도 정상적으로 해당 텍스트를 찾아낸다. 정규 표현식에서 중요하게 다뤄지는 특수문자는 . $ ^ { [ ( | ) * + ? \ 이 있다. 이 특수문자들은 문법에서 중요한 역할을 하기 때문에, 실제로 내가 찾고자 하는 텍스트에 이 특수문자들이 포함이 된다면, 앞에 \기호를 하나 더 붙여서, "이 특수기호는 패턴이 아니라, 실제로 내가 찾으려고 하는 특수문자다"라는 뜻을 확실히 알려야 한다.

정규 표현식의 문법

기초적인 문법

  • . 어떤 단어든 점의 개수만큼 매칭된다. /..../ 이런 정규식이 있다면 네 글자(공백 포함)가 매칭된다.
  • [] 대괄호 사이에 특정한 패턴을 삽입할 수 있다. /[abcd]/ 이런 식의 정규식이 있다면 괄호 속의 네가지 문자와 일치하는 단 하나의 문자와 매칭이 될 것이다.
  • [a-z] 대괄호 사이에 특정문자1-특정문자2가 존재할 때 특정문자1과 특정문자2 사이에 있는 모든 문자열이 매칭 가능한 패턴이 된다. a-z라면 모든 알파벳 소문자를 A-Z라면 모든 알파벳 대문자를 0-9는 모든 숫자, 가-힣 은 모든 온전한 형태의 한글 문자(자음 단독, 모음 단독 일치 안됨)와 일치된다. 숫자는 \d, 영문자는 \w 와 같이 짧게 기술할 수도 있지만, 보기에 더 편한 방식으로 사용하면 된다.
  • [^a-z] 대괄호 속의 첫번째 문자가 ^인 경우, 그 다음부터 오는 패턴 (이 경우에는 모든 알파벳 소문자)는 매칭 대상에서 제외된다. ^는 대괄호 안에 있을 때와 밖에 있을 때 뜻이 다르므로 주의한다. 실제로 ^ 기호를 매칭하고 싶다면 이스케이프 문자인 역슬래시(\)를 사용한다.
  • ^ 대괄호 안에 있지 않은 ^ 기호는 문자열의 시작 부분을 나타낸다. 그러니까 해당 기호 다음에 오는 패턴과 일치하는 단어더라도, 해당 단어가 문자열의 시작 부분에 있지 않으면 매칭되지 않는다.
  • $ ^와 반대로 문자열의 끝과 매칭된다. /^안녕$/ 이렇게 패턴을 작성하면 "안녕하세요"는 매칭될 수 없다.

수량을 나타내는 기호

  • * 앞에 존재하는 문자(혹은 패턴)이 0번 이상 반복되는 문자열을 찾을 때 사용한다. 예를 들어 /ca*t/ 라는 정규 표현식은 "caaaat", "cat", "ct" 모두 매칭될 수 있다. 
  • + 앞에 존재하는 문자(혹은 패턴)이 1번 이상 반복되는 문자열을 찾을 때 사용한다. *와 달리 해당 패턴이 존재하지 않는 문자열은 매칭되지 않는다.
  • ? 앞에 존재하는 문자는 있을 수도 없을 수도 있을 때 사용한다. (정확히는 0개 혹은 1개)
  • \ 위에서 기술한 바와 같이 (역슬래시)는 특정한 기호들 . $ ^ { [ ( | ) * + ? \ 을 그 기호 그대로 읽힐 수 있도록 만들어주는 이스케이프 문자이다.
  • {1} 앞에 존재하는 패턴이 정확히 1번 나타날 때 매칭된다.
  • {1,} 앞에 존재하는 패턴이 1번 이상 나타날 때 매칭된다. (+와 같음)
  • {1,3} 앞에 존재하는 패턴이 1번 이상 3번 이하일 때 매칭된다.
  • *? +? {}? *이나 +, 또 {min, max} 뒤에 ?이 붙으면, 최대한 넓은 범위로 매칭되려는 정규표현식의 Greedy한 탐색 로직이 Lazy한 방식으로 동작한다.

그룹을 나타내는 기호

  • () 괄호 내의 문자는 어떠한 그룹으로 인식이 된다. replace 기능을 사용하거나, 단어를 추출할 때 정규 표현식을 쓴다면, 괄호 안에 있는 패턴들은 나타난 순서대로 $1, $2, $3... 에 매칭된다. 
  • (word|letter) 특수문자 | 는 or의 역할을 한다. 양쪽에 있는 패턴 중 하나라도 일치하는 문자열에 매칭된다.
  • (?:) 괄호 내에 ?:이 처음으로 들어오는 경우 해당 패턴들이 존재하는 지는 판별을 하지만, 매칭된 결과에 포함되지는 않는다. $n 에도 들어가지 않는다.
  •  
  • $0 정규표현식이 아니라, 매칭 결과를 다룰 때, 이 기호는 매칭된 문자열 전체를 뜻한다.
  • $1, $2... 매칭 결과를 다룰 때 이 값은 매칭된 그룹들을 순서대로 표현한다.

미리 정의된 글자 패턴

  • \d (digit) 숫자를 뜻한다. \D의 경우 숫자가 아닌 모든 문자에 해당한다.
  • \w (word) 영문자(와 언더바_)를 뜻한다. \W의 경우 영문자가 아닌 모든 문자에 해당한다.
  • \s (space) 공백을 뜻한다(스페이스, 탭, 공백 문자). \S의 경우 공백이 아닌 모든 문자에 해당한다.

정규 표현식 참고 사이트

RegexOne: 정규 표현식을 간단하고 쉽게 배울 수 있는 정규 표현식 퀴즈 사이트. 보기 중 매칭되어야 하는 모든 단어에 매칭되고 매칭되지 않아야 하는 모든 단어는 매칭되지 않도록 피해야 한다. (위의 우측 이미지 출처)

Regex: 정규표현식을 배우기에 아주 좋은 기능들이 많은 사이트. Text에 원하는 대상 문자열들을 입력해 놓고, 정규표현식을 작성하면 라이브로 타겟이 매칭되는 것을 볼 수 있다. 또한 (?=), (?<=) 와 같이 존재하는 문법이기는 하지만 일부 브라우저나 텍스트 편집기에서 지원하지 않는 내용은 친절하게 warning 해준다. 내가 작성한 정규표현식의 예시를 링크로 제너레이트할 수 있다. (위의 좌측 이미지 출처)

Rubular: Ruby라는 프로그래밍 언어에 특화된 정규 표현식 가이드...지만 범용적인 문법만을 소개해, 많이 도움이 되었었다. Regex처럼 내가 작성한 예시의 링크를 만들 수 있다.

Email Address Regular Expression 자바스크립트, 파이썬 등의 언어에 최적화된 이메일 유효성 확인 정규 표현식을 (자체 조사 결과로는 99.9% 매칭된다고) 제공하는 사이트. 거의 모든 도메인(과 그 사이트마다 가지고 있는 아이디 규칙)에 해당하는 정규표현식이라 다소 길다 느껴지는 감이 있다.

Regex CheatCheet 위의 사이트에서 만든 치트시트(컨닝페이퍼..?). 많은 문법을 소개해주고 있지만 최신 문법의 경우 어떤 곳에는 적용되지 않는지는 알려주지 않음...

초보자를 위한 정규표현식 가이드(자바스크립트 기준): 우아한 형제들 김민태 기술이사님이 2014년도에 작성하신 슬라이드 파일. 핵심이 잘 나와있어서 공유

유튜버 드림코딩 엘리님의 정규표현식 가이드: 핵심적인 부분만 잘 요약해주셨다.

반응형

댓글