본문으로 건너뛰기
2022. 6. 1·약 7분

자바스크립트 정규표현식: 메서드와 문자 집합 | Part 1

대괄호가 감싼 흰 판 안에 분홍 역슬래시와 파란 원·네모·세모가 나란히 놓인 그림

정규표현식이란?​

정규표현식은 문자열의 패턴을 표현하는 형식 언어입니다. 정규식, regex, regexp라고도 부릅니다. 참고

정규표현식은 정해진 형식의 문자열을 찾거나 바꾸고, 텍스트에서 필요한 값을 추출할 때 유용합니다. 다만 중첩 구조가 있는 HTML을 파싱하거나 외부 HTML을 안전하게 정제할 때는 전용 파서와 새니타이저를 사용해야 합니다. 이 글은 정규표현식을 공부하며 정리한 기본 문법과 JavaScript 예제입니다.


정규표현식의 역사​

  • 정규표현식은 수학자 스티븐 클레이니(Stephen Kleene)가 기술한 정규 언어에 뿌리를 두고 있습니다.
  • Unix의 텍스트 처리 유틸리티들은 여러 형태의 정규표현식을 사용해 왔습니다.
  • 여러 변형이 생긴 뒤 1992년 POSIX 표준으로 정리되었습니다.
  • Perl은 1980년대 후반부터 여러 정규표현식 기능을 널리 알렸습니다. 필립 하젤(Philip Hazel)이 1997년에 만든 PCRE는 Perl과 호환되는 문법을 구현한 영향력 있는 엔진 중 하나입니다. JavaScript의 정규표현식 문법과 동작은 ECMAScript 명세가 별도로 정의합니다.

자바스크립트에서의 정규표현식​

  • 자바스크립트에서 정규표현식은 객체입니다.
  • 정규표현식 객체(RegExp)는 생성자 함수 또는 리터럴 문법으로 만들 수 있습니다.
    • var regex1 = new RegExp('hello'); - 생성자
    • var regex2 = /world/; - 리터럴 문법 ✅
  • 정규표현식 객체의 메서드 또는 String 객체의 메서드로 정규 표현식을 다룰 수 있습니다.

정규표현식 관련 메서드​

RegExp 객체 메서드​

  • test : 정규식 패턴과 문자열의 일치(match) 여부를 불린으로 반환합니다.
  • exec : 일치 정보가 담긴 배열을 반환하며, 일치하지 않으면 null을 반환합니다.
  • toString : 정규식 문법을 문자열로 변환하여 반환합니다.

String 객체 메서드​

  • match : 일치 결과를 배열로 반환합니다. g 플래그 유무에 따라 배열의 내용이 달라지며, 일치하지 않으면 null을 반환합니다.
  • search : 정규식 패턴과 일치한 문자열의 인덱스를 반환합니다.
  • replace : 정규식 패턴과 일치하는 문자열을 바꿉니다.
  • split : 인자로 전달된 정규식을 기준(델리미터)으로 문자열을 분할하여 배열에 담아 반환합니다.

RegExp.test(string)​

문자열 안에 정규표현식과 일치하는 부분이 있으면 true를 반환합니다.

const txt = "Programming courses always starts with a hello world example.";
let regex1 = new RegExp("hello");
let regex2 = /hop/;

console.log(regex1.test(txt)); // true
console.log(regex2.test(txt)); // false

RegExp.exec(string)​

첫 번째 일치 문자열과 그 위치, 원본 입력 등의 정보를 담은 배열을 반환합니다. 일치하는 값이 없으면 null을 반환합니다.

regex2 = /world/; // 아래 캡처처럼 hello와 world를 각각 찾습니다.
regex1.exec(txt);
regex2.exec(txt);

exec 로 hello 와 world 를 각각 찾은 콘솔 결과. index 가 41 과 47 로 나온다

String.match(RegExp)​

test, exec와 달리 문자열의 메서드입니다. g 플래그가 없으면 exec처럼 첫 일치와 캡처 그룹 정보를 반환합니다. g가 있으면 전체 일치 문자열들을 배열로 반환하고 캡처 그룹은 포함하지 않습니다.

txt.match(regex1);
txt.match(regex2);

match 로 같은 두 패턴을 찾은 콘솔 결과

String.search(RegExp)​

문자열에서 처음 일치한 위치의 인덱스를 반환하며, 일치하지 않으면 -1을 반환합니다.

txt.search(regex1); // 41

String.replace(RegExp, String)​

전달된 패턴을 찾아 두 번째 인자의 문자열로 바꿉니다. 원본 문자열은 바꾸지 않고 새 문자열을 반환합니다.

txt.replace(/hello/g, "hi"); // hello를 hi로 바꿉니다.
// Programming courses always starts with a hi world example.

String.split(separator)​

전달된 문자열이나 정규표현식을 구분자(delimiter)로 사용해 문자열을 나누고 배열로 반환합니다.

hello와 world로 문장을 나눴을 때

let txt = "Programming courses always starts with a hello world example.";

let regex1 = /hello/;
let regex2 = /world/;

// 정규표현식과 일치하는 부분을 구분자로 사용합니다.
console.log(txt.split(regex1));
console.log(txt.split(regex2));

split 결과 콘솔. 패턴을 기준으로 문자열이 두 조각으로 나뉘었다

공백(\s)으로 문자열을 나눴을 때

// 공백 문자 하나를 기준으로 나눕니다.
let regex3 = /\s/;
console.log(txt.split(regex3).map((ele) => ele.trim()));

공백으로 split 한 결과. 문장이 단어 단위 배열로 나뉘었다


메타캐릭터(Metacharacters) 이해하기​

let re = /hello/;
here help hello
🙅‍♂️         🙅🏻‍♀️        🙆‍♂️

정규표현식 엔진은 문자열의 각 위치에서 패턴이 일치하는지 검사합니다. 리터럴만으로 표현하기 어려운 '아무 문자', '숫자', '줄의 시작' 같은 조건에는 메타 문자를 사용합니다.

^$.*+?=!:|\/()[]{}

와일드카드 (.)​

와일드카드(Dot)는 개행을 제외하고 모든 글자와 일치합니다.

정규식 테스터에서 와일드카드 패턴이 that, hot, h@t, h4t 에 모두 일치하는 화면

h와 t 사이에 공백, 탭 등 어떤 문자 하나가 와도 일치합니다. 단, 기본 설정에서는 개행 문자와 일치하지 않습니다.

이스케이핑 (\)​

  • 일반적인 문자와 숫자는 그 문자 그대로 일치합니다.
  • ., *, ?처럼 정규식 문법에 쓰이는 기호를 문자 그대로 찾으려면 역슬래시(\)로 이스케이프합니다.
  • !, , 같은 문장부호는 보통 이스케이프할 필요가 없습니다. 특히 u 모드에서는 허용되지 않는 이스케이프가 문법 오류를 일으킬 수 있습니다.

\.과 \*는 점과 별표를 문자 그대로 찾고, \\는 역슬래시 자체를 찾습니다. \t, \n, \r은 각각 탭, 줄바꿈, 캐리지 리턴을 나타냅니다. \u00A9처럼 유니코드 코드 단위를 이스케이프하면 ©와 일치합니다.

정규식 테스터에서 백슬래시를 한 번 더 붙여 d 와 백슬래시를 함께 선택한 화면

d와 역슬래시를 함께 찾으려면 역슬래시 자체를 \\로 이스케이프합니다.

제어 문자​

탭, 개행에 대응하는 메타캐릭터도 있습니다.

  • \t = tab
  • \v = vertical tab
  • \n = newline
  • \r = carriage return

탭 일치

탭 이스케이프를 넣은 패턴이 h 와 t 사이의 탭에 일치하는 화면

개행 일치

개행 이스케이프를 넣은 패턴이 줄바꿈이 낀 h 와 t 에 일치하는 화면

CR(\r)과 LF(\n)의 차이​

\r은 Carriage Return(CR), \n은 Line Feed(LF)를 나타냅니다. CR(\r), LF(\n)이란 무엇인가? : 네이버 블로그

  • CR과 LF는 타자기와 텔레타이프에서 유래한 제어 문자입니다.
  • Unix 계열 운영체제는 줄바꿈에 LF를, Windows는 주로 CRLF를 사용합니다.

줄바꿈 문자를 처리하지 못하는 오래된 편집기에서는 다른 운영체제에서 만든 파일의 줄이 제대로 나뉘지 않을 수 있습니다.


문자 집합(Character Sets)​

대괄호 안에 문자 집합을 쓰면 그중 한 문자와 일치합니다.

Sets [ … ]

대괄호로 묶은 문자 중 하나와 같으면 일치합니다.

gray 또는 grey 찾기​

  • let re = /gr.y/ 점은 임의의 문자 하나와 일치하므로 gray, grey뿐 아니라 groy도 선택될 수 있습니다.

  • let re = /gr[ae]y/ 문자 집합을 사용하면 가운데 글자가 a 또는 e인 단어만 선택합니다.

gr 대괄호 ae y 패턴이 gray 와 grey 만 고르고 groy 는 지나치는 화면

문자 집합을 연달아 사용할 수도 있습니다.

/[rh][abcde][ i]/g는 r 또는 h, a부터 e까지의 문자 하나, 공백 또는 i를 차례로 찾습니다.

캐릭터 셋 세 개를 이어 붙인 패턴이 문장에서 세 글자 묶음을 골라내는 화면

문자 집합의 범위​

Range /[1-4]/

문자 집합 안의 하이픈은 범위를 나타냅니다.

  • /[1-9]/ = 1부터 9까지의 숫자
  • /[a-e]/ = a와 e 사이의 알파벳
  • /[1-6][1-6]/ = 1과 6사이의 숫자 + 1과 6사이의 숫자
  • /[0-9a-zA-Z ~,]/ = 숫자, 영문 대소문자, 공백, ~, , 중 하나
  • /[12\-5]/ = 1 또는 2 또는 하이픈 또는 5
  • /[12-5]/ = 1 또는 2부터 5 사이의 숫자

문자 클래스의 범위는 문자 하나를 선택합니다. [10-20]처럼 여러 자리 수의 범위를 나타낼 수는 없습니다.

10부터 20 범위처럼 보이는 패턴이 13의 1과 20의 2·0을 한 글자씩 고르는 화면

이 문자 집합의 구성 요소는 1, 0-2 범위, 마지막 0입니다. 중복을 합치면 10부터 20까지의 수가 아니라 0, 1, 2 가운데 한 글자와 일치합니다.

한글 음절·자모와 숫자를 한 문자 집합으로 묶으면 /[가-힣ㄱ-ㅎㅏ-ㅣ\d]/g처럼 쓸 수 있습니다.

한글 음절·자모와 숫자에 일치하는 문자 집합을 정규식 테스터에서 실행한 화면

특정 문자 제외하기​

문자 집합의 첫 자리에 캐럿(^)을 붙이면 그 집합에 속하지 않는 문자와 일치합니다.

[^a-z]는 영문 소문자 이외의 문자에 일치합니다. 한글과 숫자뿐 아니라 대문자, 공백, 문장부호도 포함됩니다.

아래처럼 제외할 문자의 범위를 더 지정할 수도 있습니다.

영문 대소문자를 제외한 나머지 문자에 일치하는 정규식 테스터 화면

문자 집합의 단축형​

포함 단축형​

\d​

숫자(Digits) 하나와 일치합니다. [0-9]와 같습니다.

숫자 단축형 d 가 문자열 속 12345 에만 일치하는 화면

\w​

알파벳, 숫자, 언더스코어 가운데 한 문자와 일치합니다. [a-zA-Z0-9_]와 같습니다.

단축형 w 가 알파벳, 숫자, 언더스코어에 일치하고 공백은 건너뛰는 화면

\s​

[ \t\r\n\v\f] 등 공백 문자(White Spaces) 하나와 일치합니다. 유니코드 공백도 포함합니다.

단축형 s 가 공백과 탭에만 일치하는 화면

제외 단축형​

\D​

숫자(Digits)가 아닌 문자 하나와 일치합니다. [^0-9]와 같습니다.

대문자 D 단축형이 숫자를 뺀 나머지 문자에 일치하는 화면

\W​

대소문자 알파벳, 숫자, 언더스코어가 아닌 문자 하나와 일치합니다. [^a-zA-Z0-9_]와 같습니다.

대문자 W 단축형이 알파벳, 숫자, 언더스코어를 뺀 문자에 일치하는 화면

\S​

[^ \t\r\n\v\f]처럼 공백 문자(유니코드 공백 포함)가 아닌 문자 하나와 일치합니다.

대문자 S 단축형이 공백을 뺀 문자에 일치하는 화면


좋은 사람들과 재미있는 일을 하며 열정적이고 즐겁게 살고 싶은 개발자