목차

간단한 예제를 통해 보는
자바스크립트 정규 표현식

제목에 자바스크립트는 이 포스트에서 자바스크립트를 사용해 예제를 만들었다는 의미다.
여기서 설명하는 정규표현식은 다른 언어에서도 똑같이 사용할 수 있다.

정규표현식이란?

정규표현식(正規表現式, Regular Expression)은 문자열을 처리하는 방법 중의 하나로 특정한 조건의 문자를 '검색'하거나 '치환'하는 과정을 매우 간편하게 처리할 수 있도록 하는 수단이다
- 생활코딩 -

정규표현식은 용도에 따라서 쉽기도 하지만 어렵기도 합니다.

개발 초반에는 이게 뭐람! 하고 인터넷검색으로 원하는 표현식을 찾아서 복사 붙여넣기로 사용했었으나, 개발해가면서 조금씩 복잡한 혹은 일반적이지않은 패턴의 정규표현식을 요구할 때는 머리가 멍해지곤 했습니다.

표현이 너무 간결하기도 하지만 헷갈리기도 합니다. 읽기도 쉽지가 않습니다. 하지만 엄청 유용합니다.

아래 예제들을 죽 따라가면서 사용법을 익혀보도록 하겠습니다.

자바스크립트에서 정규표현식 사용하기.

아래 코드를 Console에서 실행시켜 보자.

var name = 'Kendrick B Jung';
var namePattern = /Kendrick/;
namePattern.test(name);     // true
namePattern.exec(name);     // ["Kendrick"]
name.match(namePattern);    // ["Kendrick"]

위의 주석과 같은 결과가 출력된다. 아래 각 메서드에 설명을 보자.

  • test는 Boolean을 리턴한다. 문자열이 부합하면 true, 아니라면 false
  • exec은 문자열의 시작부분을 담는 배열을 리턴한다.
    검색된 내용이 없다면 아무것도 리턴하지 않는다.
  • match는 검색된 문자열 부분의 배열을 리턴한다.
    검색된 내용이 없다면 아무것도 리턴하지 않는다.

exec과 match의 차이

우선 위 예제를 보면 알겠지만 실행인자가 다르다. match는 string에서 제공하기 때문에 name.match()와 같은 방식으로 사용한다.

그리고 exec함수는 /g(global)옵션을 넣어놔도 일치하는 첫 번째 값만 반환한다..! 하지만 캡쳐 값이 있다면 배열로 반환해준다.

var name = 'Kendrick B Jung';
var namePattern = /(k)/;
namePattern.exec(name); // ["k", "k"]

캡쳐 구문()에 대해서는 아래에서 배우니 우선 찝찝하지만 간단하게 이해하고 넘어가자.

반복

위에서 사용한 namePattern은 패턴이 전혀 아니기 때문에 단순 검색과 다름이 없다.
만약 Kendric과 Kendrick을 동시에 찾고 싶다면? 위 namePattern으로는 Kendrick만 찾을 수 있을 것이다.

?

?는 ?앞의 문자가 하나 나오거나 아예 나오지 않음을 의미한다.
아래와 같이 namePattern을 변경하면 알 수 있다.

var name = 'Kendrick B Jung';
var name_short = 'Kendric B Jung';
var namePattern = /Kendrick?/;
namePattern.test(name);         // true
namePattern.test(name_short);   // true

+

+는 앞의 문자가 하나 이상 출현하는 경우를 찾아준다.
+앞의 값이 적어도 하나 이상 있어야 하며 즉 1개 이상 반복하는 경우는 다 찾아준다.

var text = 'Wow';
var text2 = 'Wooooooow';
var regexPattern = /Wo+w/;
regexPattern.test(text);    // true
regexPattern.test(text2);   // true

위의 예제의 regexPattern을 보면 o+가 되어있다.
o가 1개이상 있어야 한다는 의미기 떄문에 text2도 true로 반환한다.

*

앞에 나오는 문자가 나오지 않거나 하나 이상 나오는 경우이다. 쉽게 말하면 해당 문자가 있어도 그만 없어도 그만.
* 앞의 값이 0개 이상 반복하는 경우는 다 찾아준다.

처음 고안한 스테판 클리니의 이름을 따 클리니 스타 라고도 한다.

var text = 'Www'; // <- o가 존재하지 않는다.
var regexPattern = /Wo*w/;
regexPattern.test(text);    // true
regexPattern.exec(text);    // ["Ww"]

o*로 인하여 o가 있다면 해당 값을 반환하며, 만약 o가 없다면 가볍게 무시한다.

예외문자

그렇다면 위 특수문자 자체를 패턴에 이용하고 싶을 때는 어떻게 사용할까?
특수문자 앞에 예외문자(\)를 붙여주면 된다.

var name = 'Kendrick * Jung';
var namePattern = /\*/ // <- \를 붙여서 특수문자 *을 검색 가능
namePattern.test(name); // true

길이를 지정하기

{1,10} 같은 형태로 사용한다.

{n} : 앞에 오는 문자가 n번 연속해서 나오는 경우
{n,} : 앞에 오는 문자가 최소 n번 연속해서 나오는 경우
{m, n} : 앞에 오는 문자가 최소 m번, 그리고 최대 n번 연속해서 나오는 경우

var text = 'Amaaaaaazing';
text.match(/ma{2}/);    // ["maa"]
text.match(/ma{2,}/);   // ["maaaaaa"]
text.match(/ma{2,4}/);  // ["maaaa"]

.

경우에 따라 모든 문자열을 의미하는 패턴이 필요하다.
Wow와 ! 사이에 어떤것이 와도 상관이 없게 마늘고 싶다면 .를 사용할 수 있다.

var text = 'Wow amazing!';
text.match(/Wow.*!/);   // ["Wow amazing!"];

. 즉 모든 문자열에 개수가 상관없이 찾을 수 있게 *을 붙여줬다.

[]

대괄호는 내부에 있는 문자를 각각 검색한다.

var text ='English';
text.match(/[abcdefghifklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ]*/);
// ["English"]

위와같이 쓰기는 지저분하니 범위표현인 -를 사용하면 아래와 같이 사용 할 수 있다.

var text ='English1234';
text.match(/[a-zA-Z0-9]*/);
// ["English1234"]

0-9의 범위도 검색 할 수 있게 추가 했는데 한눈에 알아 보실 수 있으실 듯.

아래와 같이 사용하는 것도 가능합니다.

text.match(/[abcde0-9\-]/);

살펴보면 abcde의 소문자와 0~9까지의 숫자 그리고 \예외문자를 추가하여 -자체를 문자열 검색하는 정규식이다.

^ (Negative)

프로그래밍언어의 !와 비슷하다.

var text = 'English';
text.match(/[^lgEn]+/); // ["ish"]

lgEn 가 포함된 문자를 제외하고 나머지 문자열을 +를 통해서 검색했다.
결과적으로 ish가 노출된다..

캡쳐링 그룹

캡쳐링 그룹이란 정규식 안의 작은 표현식과 같은 것으로, 특수 문자도 그대로 사용할 수 있다.

(?:그룹)

var textPattern = /(?:fi){1,3}/;
textPattern.exec('test fififififi'); // ["fififi"]

var textPattern2 = /t(?:fi|est)/; // pipe라인을 이용하여 여러 문자열을 비교한다
'test text'.match(textPattern2); // ["test"]
'text tfitest'.match(textPattern2); // ["tfi"]

캡쳐링 그룹은 소괄호 안에 표현된다.
위에서는 ?에 특정 문자를 할당하는 방식으로 사용했지만 아래와 같이 사용할 수 있다.

연산자의 ()와 비슷한 기능을 한다.

var cellphonePattern = /^01([0|1|6|7|8|9]?)-?([0-9]{3,4})-?([0-9]{4})$/;

url패턴을 체크하는 정규식이다. () 캡처 그룹을 통해서 어떻게 나눠 체크하는지 파악할 수 있다.

대괄호의 축약형

대괄호의 축약형을 지원한다.
예를들면 [0-9]는 \d 와 같이 사용할 수 있다.

\d	- Match any character in the range 0 - 9 (equivalent of POSIX [:digit:])
\D	- Match any character NOT in the range 0 - 9 (equivalent of POSIX [^[:digit:]])
\s	- Match any whitespace characters (space, tab etc.). (equivalent of POSIX [:space:] EXCEPT VT is not recognized)
\S	- Match any character NOT whitespace (space, tab). (equivalent of POSIX [^[:space:]]).
\w	- Match any character in the range 0 - 9, A - Z, a - z and underscore (_) [0-9A-Za-z_]. Equivalent of POSIX [:word:])
\W	- Match any character NOT the range 0 - 9, A - Z, a - z and punctuation (equivalent of POSIX [^[:graph:]])

Positional Abbreviations

\b	- Word boundary. Match any character(s) at the beginning (\bxx) and/or end (xx\b) of a word, thus \bton\b will find ton but not tons, but \bton will find tons.
\B	- Not word boundary. Match any character(s) NOT at the beginning(\Bxx) and/or end (xx\B) of a word, thus \Bton\B will find wantons but not tons, but ton\B will find both wantons and tons.

Flag

플래그를 통해서 기본 동작을 변경 할 수 있다.

g - Global Flag

문자열 내의 모든 패턴을 찾는다.
정규 표현식은 매치되는 문자열을 찾으면 검색을 중단하지만, 이 Flag를 사용하면 매치되는 모든 문자열을 찾는다.

i - Ignore Case

문자열의 대소문자를 구별하지 않는다.

m - Multi Line

문자열 행이 바뀌어도 찾는다.

아래와 같이 사용한다.

var regExp = /\s/g; // 모든 공백문자열을 검색한다.

마치며

정규표현식은 언제 어디서든 필요하지만 제대로 깊게 파본 적이 없는 것 같습니다.
사실 필요한 정규표현식은 검색으로 대부분 해결할 수 있기 때문에 더욱 그런데 이참에 기본적인 부분만이라도 정리를 해봤습니다.

Atom 에디터를 사용하는 유저라면 텍스트 에디터에서 직접 수정하면서 테스트 해보거나 기본적으로 유용한 정규표현식이 준비되어있는 아래 패키지를 추천드립니다.
Atom package - regex-filter-and-generator

참고

regexper.com - 정규식을 시각화해서 보여주는 사이트
다시 시작하는 프로그래밍 - 자바스크립트로 배우는 웹 프로그래밍 A to Z
케이님의 블로그
Nextree 정규표현식을 소개합니다 (정규 표현식의 시각화))
전화번호 체크 정규식
atom package - regex-filter-and-generator