정규표현식 \b \B의 단어 경계(word boundary)

단어 경계는 \w와 \W의 그 사이를 찾는 작업

정규표현식(regular expression)을 사용해 일치(match)하는 단어나 기호를 찾는 것은 매우 간단합니다.

My name is ABC.

ABC는 정규표현식 /ABC/를 사용하면 간단하게 찾을 수 있습니다.

그러나 다음 문자열에서 to를 찾기 위해 /to/를 사용하면 의도한 결과를 벗어납니다.

She told me not to go.

to가 포함된 모든 단어를 검색하는데요.

이 때 /b를 사용해 경계를 지정하면 원하는 부분만 찾을 수 있습니다.

그렇다면 /b의 정확한 기능은 무엇일까요?


1. /b의 기능

/b는 문자(\w에 해당하는 문자, a-z,A-Z,0-9,_)와 비(非)문자(\W에 해당하는 경우) 부분의 경계를 의미합니다.

이 부분의 이해가 어려울 수도 있는데요.

예를 들어 보겠습니다.

문자(\w로 표현): abcdefzhijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_
비문자(W로 표현) : 위 문자를 제외한 모든 기호

위와 같은 정의를 갖는 문자와 비문자 사이의 경계를 나타냅니다.

참고로 문자의 \w는 w가 소문자, 비문자의 \W는 대문자입니다.

띄워쓰기는 비문자에 해당하므로 /b를 사용해 단어의 경계를 정하고 원하는 결과를 만들 수 있는 것입니다.

그럼 다음 상황을 확인해보죠.

/\ba/g

위 표현식을 사용했을 때 다음 문자열에서 찾을 수 있는 결과는 무엇일까요?

-a

‘ a’

_a

aa

star

결과는 다음과 같으며 한 줄로 표현하겠습니다.

aa‘ _a aa star

-a에서 a가 선택되는 이유는 -가 비문자이며 a가 문자이므로 \b는 두 사이를 가리키기 때문입니다.

‘ a’에서도 a 앞의 띄워쓰기는 비문자, a는 문자이므로 \b는 두 사이를 가리킵니다.

_a에서 a가 선택되지 않는 이유는 _ 기호는 문자로 취급하며 a도 문자이기 때문입니다.(\w의 정의)

aa에서 a가 선택된 이유는 문자열 제일 앞 또는 제일 뒤가 문자면 \b의 조건에 해당한다고 정의하기 때문입니다.

따라서 위의 문장에서 to만 찾으려면 다음과 같은 표현식을 사용하면 됩니다.

/\bto\b/g

She told me not to go.

참고로 \b, \B는 경계만을 가리킬 뿐 실제 문자와 일치하는 것은 아니므로 결과에는 포함되지 않습니다.


2. /B의 기능

그렇다면 대문자로 표현되는 \b의 반대 기능 \B의 정의는 무엇일까요?

바로 비문자와 비문자 사이의 경계, 또는 문자와 문자 사이의 경계를 의미합니다.

!-! abc와 같은 비문자 사이에서 비문자(-)를 찾거나 문자 사이에서 문자(b)를 찾을 수 있습니다.

/\B-\B/g

!! ‘


3. 활용

\b, \B는 주로 단어 검색에 유용합니다.

이 기능의 명칭이 단어 경계(word boundary)이므로 용도는 명확합니다.

문자열 내 의도하지 않은 기호의 탐색이나 카멜케이스(CamelCase)등과 관련된 작업에도 사용할 수 있습니다.



쉽고 빠른 정규표현식(Easy Regular Expression, regex)

정규표현식(Regular Expression)의 구성과 의미, 자바스크립트에서 사용하기

정규표현식(Regex)은 검색 패턴을 지정하여 기호로 표시한 것입니다.

이 개념은 미국의 수학자인 Stephen Cole Kleene가 1950년대에 정의한 정규 언어(Regular Language)와 관련이 있으며, 정규표현식 문법은 1980년대 Perl에서부터 사용되기 시작했습니다.

주로 검색 또는 치환 작업에 사용되며, 현재 대부분의 프로그래밍 언어에서 정규표현식을 지원하거나 라이브러리를 통해 사용할 수 있습니다.

예를 들어 다음 문장에서 특정 조건에 따른 검색을 진행하고자 할 때, 정규표현식을 사용할 수 있습니다.

The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it.

  • too를 찾고자 할 때 -> /too/
    The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it.
  • 대소문자 구분 없이 t를 모두 찾고자 할 때 -> /t/-gi
    The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it.
  • d로 시작하는 단어 및 문자를 모두 찾고자 할 때 -> /[d]\w+/-gi
    The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it.
  • ea가 들어가는 단어를 찾고자 할 때 -> /[a-z]*ea[a-z]*/-i
    The greatest danger for most of us is not that our aim is too high and we miss it, but that it is too low and we reach it.

다음 사이트를 이용하면 의도한 대로 정규표현식이 작성되었는지 확인할 수 있어 매우 유용합니다.

regexr.com

Expression 아래에 식을 삽입하고, 그 아래 상자에는 검색 대상이 될 텍스트를 입력하면 됩니다.

그럼 먼저 표현식이 나타내는 의미에 대해 알아본 뒤, 자바스크립트에서 편리하게 사용하는 방법을 확인해 보겠습니다.


1. 정규표현식 기호의 종류

  • / . / → 모든 문자
  • / + / → 하나 이상의 문자
  • / ? / → 0 개 또는 1개의 문자
  • / ^ / → 해당 문자를 제외
  • / / → 범위 지정
  • / * / → 0 개 또는 1개 이상의 문자
  • / [ ] / → 집합 구성
  • / { } / → 반복 횟수 지정
  • / \ / → 이스케이프 문자
  • / \d / → 모든 숫자
  • / \D / → 숫자가 아닌 문자
  • / \w / → 알파벳, 숫자, 밑줄_ 문자
  • / \W / → 알파벳, 숫자, 밑줄_이 아닌 문자
  • / \s / → 공백 문자
  • / \S / → 공백이 아닌 문자
  • / \n / → 줄 바꿈 문자

정규표현식의 가장 기본이 되는 기호와 의미는 위와 같으며, 위 기호의 사용법만 익힌다면 정규표현식의 기본적인 이해는 가능할 것입니다.

그럼 각 기호의 사용 예제를 통해 사용법을 익혀보도록 하겠습니다.


2. 기호의 의미

정규 표현식에서 가장 기초가 되는 부분이므로 외워두면 유용하게 사용할 수 있습니다. d는 숫자, w는 영문자, 숫자, _, s는 공백, n은 줄바꿈을 의미하며, 각 단어의 대문자는 NOT(반대)을 의미합니다.

  • 숫자가 한 번 이상 반복되는 문자 검색 👉 / [\d]+ /
  • 숫자가 아닌 문자 검색(공백 포함) 👉 / [\D] /
  • 괄호가 포함된 문자, 숫자 검색 👉 / \([\w]+\) /
  • 영문자, 숫자, _ 가 아닌 문자 검색 👉 / [\W]+ /
  • 공백을 검색 👉 / \s /

regexr.com에 검색할 대상이 되는 문장을 붙여 넣거나 직접 작성한 뒤 원하는 패턴으로 표현식을 직접 만들어보면 정규 표현식에 금방 익숙해질 수 있습니다.


이스케이프란 무엇일까요? 키보드 왼쪽 상단에 있는 ESC 버튼이 이스케이프의 약자입니다. 바로 벗어나다는 뜻인데요.

여기서는 기존에 지정된 약속에서 벗어난다는 뜻으로 보면 됩니다.

예를 들어서 .(마침표, dot)의 경우 모든 문자를 의미하는 뜻으로 사용됩니다.

하지만 때로는 글자 그대로 마침표 기호를 의미하고 싶은 경우도 있는데요. 이 때 이스케이프 문자를 사용하면 ‘우리 약속했던 것에서 벗어나자’는 뜻으로 사용할 수 있습니다.

  • 모든 문자를 의미. a, b, c, d, ?, !, @, , 등 모든 문자 중 하나를 의미 👉 / . /
  • 오직 .(마침표)만을 의미 👉 / \. /
  • 하나 이상의 문자를 의미 👉 / + /
  • 오직 +(플러스)만을 의미 👉 / \+ /

이스케이프는 매우 유용한 필수 기능이므로 이스케이프가 필요한 문자를 확인해 둘 필요가 있습니다.


정규 표현식에서 특정 기호는 특별한 의미를 갖습니다. 대표적인 기호의 사용법은 다음과 같습니다.

  • 소문자 a~z 또는 대문자 A~Z 내 일치하는 영문자 검색 👉 / [a-zA-Z] /
  • color 또는 colour를 검색(u가 있어도 되고 없어도 됨) 👉 / colou?r /
  • a를 포함하는 단어 검색 👉 / [\S]*a[a-zA-Z]* /
  • a-z 또는 공백(space)이 아닌 문자 검색 👉 / [^a-z ] /
  • 영문자로 시작하여 반드시 숫자 또는 특수 기호를 포함하는 문자열 검색 👉 / [a-zA-Z]+[\d!@#\$%\^*]+[\w]* /

중괄호는 반복 횟수를 지정하며, 이를 사용하면 검색 패턴의 상세한 지정이 가능합니다.

중괄호에 하나의 숫자를 넣으면 전체 반복 횟수를 의미하며, 두 개의 숫자는 시작과 끝의 범위를 의미합니다.

예를 들어 {3}이면 패턴을 3번 반복하라는 의미를 가지며, {1, 3}은 범위 구간이 1에서 3까지임을 의미합니다.

{1, }과 같은 표현도 가능하며, 이는 + 기호와 같은 의미, 즉 하나 이상이라는 의미를 갖습니다.

  • A가 3번 반복되는 문자를 검색 👉 / [A]{3} /
  • 3자리 이상인 숫자를 검색(3번 이상 반복) 👉 / [\d]{3,} /
  • A가 2번에서 3번 반복되는 문자를 검색(반복 범위 지정) 👉 / [A]{2,3} /

반복 횟수만 지정하면 의도하지 않은 결과도 함께 검색되는 경우가 많아 하위표현식 및 전후방 탐색과 함께 사용하면 더욱 효과적인 패턴의 사용이 가능합니다.


대괄호 내 기재된 기호로 검색할 패턴을 지정합니다. 기호를 직접 기입하거나 범위 지정 기호인 -를 사용해 검색 패턴을 지정할 수 있습니다.

  • 지정한 문자(a 또는 A 또는 b 또는 B 또는 c 문자)를 하나 검색 👉 [aAbBc]
  • a에서 e까지(a,b,c,d,e)의 범위 내 문자하나 검색 👉 [a-e]
  • 제외 문자인 ^가 있으므로 a-z 범위에 들어가지 않는 문자 또는 기호를 하나 검색 👉 [^a-z]
  • 지정 기호 중 하나를 검색 👉 [?!@#$%^&*()_]
  • c 또는 C로 시작하여, a-z 중 하나로 끝나는 단어 검색 👉 [cC][a-z]

[ ] 내 기재된 기호는 하나의 문자 또는 하나의 기호를 대상으로 검색하므로 한 글자 이상을 검색하고 싶은 경우에는 +(하나 이상의 문자) 또는 *(0개 또는 1개 이상의 문자)를 붙여줘야 합니다.

  • 한 개 이상의 a-z 문자를 검색(반드시 1 개 이상 존재하는 조건) 👉 [a-z]+
  • 0 개 이상의 A-Z 문자를 검색(있을 수도 있고 없을 수도 있는 조건) 👉 [A-Z]*

위 조건은 특정 구성을 갖는 문자열 검색에 효과적이며, 예를 들어 이메일 주소가 있습니다.

이메일 주소 형식인 abcd@xyz.com을 검색하기 위해서는 다음과 같은 검색 패턴을 사용할 수 있습니다.

/[a-zA-Z0-9]+@[a-zA-Z0-9]+\.[a-zA-Z]+/

패턴을 분석해 보겠습니다.

먼저 이메일의 아이디에 해당하는 부분은 영문자 및 숫자로 이루어질 수 있으므로 [a-zA-Z0-9]로 시작하고, 하나 이상의 문자이므로 +기호를 붙여줍니다.

아이디가 끝나는 부분에 @가 따라오므로 @를 기입하고, 뒤의 호스트 주소 역시 하나 이상의 영문자와 숫자로 지정합니다.

.com 형식의 주소이므로 .(마침표, dot)문자와 일치시키기 위해 이스케이프로 .(마침표, dot)을 지정해주고, 다시 하나 이상의 영문자를 지정하여 이메일 검색 패턴을 생성합니다.

아이디에 .(마침표, dot)이 들어가거나 호스트 주소가 .co.kr의 형식이 되는 경우에는 위 패턴에서 약간의 응용이 필요합니다.



3. 종합 정리

정규 표현식은 처음 보면 마치 외계어처럼 기존의 프로그래밍 언어와는 다른 모습을 하고 있습니다.

선뜻 다가가기 어렵거나 거부감이 들기도 하는데요. 알고나면 생각보다 간단하고 규칙적인 구조를 가지고 있어 마음이 놓이기도 하고 검색에 응용할 수 있는 부분이 많은 것을 깨닫습니다.

위에서 소개한 부분은 아주 기초적인 부분이며 대표적인 기능을 소개하기 위한 간략한 샘플 패턴이므로 정말 원하는 검색 패턴을 구현하기 위해서는 더 많은 기능을 익혀야 하고 검색 패턴도 보완되어야 할 부분이 많습니다.

추가 문의 사항이나 문제가 있는 부분은 댓글 남겨주세요.

감사합니다.