본문 바로가기

프로그래밍/javascript(ES)

자바스크립트 정규식 RegExp 사용법

웹주소인지 판별하기, 특정한 틀 안에 있는지 확인하기 등등.. 여러가지 문자열들을 자바스크립트에서 처리하다 보면, 정규식이라는 기능이 필요하곤 합니다. 특정 상황에 맞는 문자열인지 검사하거나 특정 부분만 추출해내기 위해서 이 정규식처럼 편한 기능이 따로 없기 때문이죠!

정규식이 하는 일은, 혼자서는 못 쓰이며 String과 같이 쓰일 시 문자열에서 특정 형식에 맞는 부분이 있는지 검사하거나 정규식에 맞는 문자열의 부분을 추출하는 정도입니다. 또한 일반적인 함수에서 불가능한 것들을 가능하게 만들어 주죠. 예를 들자면, 문자열의 replace 함수에서 포함된 '모든' 문자열들을 바꾼다던지 하는 것이죠. 아니면 HEX 코드가 맞는지 체크할 수도 있구요.

그럼, 이런 정규식들을 어떻게 사용하는지 알아봅시다.



정규식 생성

자바스크립트의 정규식을 사용하기 위한 방법으로는 두 가지가 있습니다. 첫번째는 일반적으로 많이 쓰는 방법인데, 리터럴로 편하게 사용하는 방법이고 두번째는 어떤 형식이던지 사용할 수 있는.. 객체 생성 입니다.

리터럴의 경우에는 절대 변하지 않는 프로그래머만 접근할 수 있는 영역에 사용하면 되고, 객체 생성의 경우에는 이용자가 입력하거나 환경에 따라서 정규식 내용이 변할 수 있는 상황에서 이용하면 됩니다.


/정규식/속성
new RegExp("정규식","속성")


정규식은 위 규칙대로 작성하면 됩니다. 윗부분은 정규식 리터럴대로 작성하는 부분이고, 아래는 정규식(RegExp) 객체를 생성해주는 구문입니다. 그리고, 속성은 생략도 가능합니다. (필요시에만 넣음)

이렇게 RegExp를 생성하는 방법에 대해서는 알았는데, 정규식을 작동하는 방법은 무엇일까요? 알아봅시다.


정규식 작동방법

정규식은 여러 함수에서 힘을 발휘할 수 있습니다. String 함수 몇개와 RegExp만의 함수 몇가지가 있는데요. 주로 사용되는 함수는 다음과 같습니다.


String.match(정규식)

String.match는 문자열에서 일치하는 항목을 알려 줍니다. 만약 정규식에 g 속성이 있다면, 일치하는 항목들을 배열로 돌려줍니다.


RegExp.test(문자열)

test 함수는 문자열에 RegExp로 테스트를 한 뒤 일치하면 true를 반환, 아니면 false를 반환해줍니다.


RegExp.exec(문자열)

exec 함수는 문자열에서 검사를 해 가장 첫번째로 검사를 통과한 항목에 대한 정보를 반환합니다. 같은 regexp 객체에서 같은 대상에 대한 검사를 한번 더 진행하는 경우, 검사를 통과했던 항목 그 뒤의 항목들을 검사한 뒤 정보를 반환합니다. 함수를 실행할때마다 이미 검사한 항목을 제외하고 검사를 한다는 점에서 String.match와 다른점이 드러납니다.



정규식 내용 작성방법


\

백슬래시는 문자열에서의 백슬래시와 똑같이, 자신의 바로 뒤에 오는 특정 기능을 하는 무언가를 아무기능도 하지 않는 일반 문자로 만들어 줍니다. 예를 들어, 정규식 리터럴에서 정규식의 시작과 끝을 담당하는 / 를 그냥 문자처럼 정규식에 넣어서 취급하고 싶다면, \/ 라고 쓰면 되는 것입니다.


^

^는 문자열의 첫부분인지를 검사합니다. 예를 들어 /^잼/ 으로 검사를 한다면 '잼통' 에는 일치하지만 '딸기잼' 에는 일치하지 않습니다.


$

$는 문자열의 마지막 부분인지를 검사합니다. 예를 들어 /식$/ 로 검사를 한다면 '수식' 엔 일치하지만 '식수' 에는 일치하지 않습니다.


*

*은 자신의 앞에 오는 문자가 0회 이상 반복되는지를 검사합니다. 문자가 없어도 참이 되므로 혼자서 검사 목적으로 쓰이기는 힘듭니다. 다만 이런 경우에 많이 쓰입니다. /으아*앙/ 으로 검사하면 '으앙!!' 에도 일치하고, '으아아아아아아아아앙!!!!' 에도 일치합니다. 하지만 '으아아아엥' 에는 일치하지 않습니다. 이런식으로 특정 항목이 몇개 있던지 상관없을 때에 쓰입니다.


+

+는 앞에 오는 문자가 1번 이상 반복되는지를 검사합니다. *과 다르게 무조건 한번은 그 문자가 와야 됩니다. /으+음/ 으로 검사할시 '으음..'과 '으으음...' 에는 일치하지만 '음.' 에는 일치하지 않습니다.


?

?는 앞에 오는 문자가 0번 또는 1번 반복되는지를 검사합니다. 그냥, "있거나 없거나"인 텍스트를 정의하면 됩니다. /물?컵/ 으로 검사할때 "물컵"과 "컵" 이 일치합니다.


.

.은 개행문자 \n를 제외한 모든 문자열 중 하나에 일치하는지 검사합니다. /.S/ 로 검사를할 경우에 "JS"는 일치하지만 "S" 는 일치하지 않습니다.


(식)

정규식을 하나로 묶어 주고, 그것을 기억합니다. (exec 함수 이용, 또는 /숫자 로 데이터 이용 가능) 포획 괄호 라고 불리며, 하나로 묶어주는 특성을 잘 이용하면 정말 편리합니다. /(JAM)+/ 라면, "JAM"과 "JAMJAM"은 일치하지만 "JA"는 일치하지 않습니다. 


(?:식)

정규식을 하나로 묶어 줍니다. 바로 위에 있는 포획 괄호랑은 다르게 그것을 기억하지는 않습니다. 이를 비포획 괄호라고 부르며, 사용방식은 위의 포획 괄호와 같습니다.


식(?=식)

첫번째 식의 뒤에 두번째 식이 뒤따라와 일치하는 경우에만 첫번째 식이 일치합니다. 여기까지만 보면 이런 기능이 왜 있나 할수도 있는데, 특이하게도 두번째 식의 결과는 exec 등을 이용했을 경우, 나오지 않습니다. /java(?=script)/ 로 검사를 할 경우 "javascript"의 검사 결과는 "java"만이 나옵니다.


식(?!식)

첫번째 식의 뒤에 두번째 식이 뒤따라와 일치하지 않는 경우에만 첫번째 식이 일치합니다. /java(?!script)/ 라면 "javajam"은 일치, "javascript"는 불일치입니다.


식|식

첫번째 식 또는 두번째 식에 일치하는지 검사합니다. 둘다 일치하지 않을시 일치하지 않는 것으로 처리합니다.


{숫자}

바로 앞에 있는 문자가 저 횟수만큼 쓰여있는지 검사합니다.


{숫자,숫자}

바로 앞에 있는 문자가 첫번째 숫자 ~ 두번째 숫자 사이의 개수로 쓰여있는지 검사합니다.


[문자들]

문자들중 하나가 있는지 검사합니다. /[abc]/ 라면 "a" 는 일치, "2" 는 불일치입니다. 여기서 사용하면 좋은 구문이 하나 있는데, 바로 - 입니다. -는 양쪽에 있는 문자 사이까지도 포함하게 해 줍니다. 예를 들어 a-d 라면 a부터 d까지의 문자를 의미합니다.


[^문자들]

문자들중에 일치하는 문자가 없는지 검사합니다. /[^abc]/ 라면 "b"는 불일치, "d"는 일치입니다.



\ 가 들어가는 특수 문자들

[\b]

백스페이스 문자를 나타냅니다.


\b

단어의 경계 부분을 나타냅니다. 예를 들자면, "ab c" 일때 ab 단어가 끝나고 공백이 있는 부분이 경계입니다. 하지만 이건 영어와 숫자, 그리고 _ 만을 단어라고 생각하고 취급하기 때문에 쓸일은 거의 없습니다.


\B

단어의 경계 부분에 있지 않은지 나타냅니다. \b 의 반대입니다.


\c문자

특수한 컨트롤 문자를 나타냅니다.


\d

숫자 문자를 나타냅니다. [0-9] 와 같은 기능을 한다고 생각하면 됩니다.


\D

숫자 문자가 아닌 문자를 나타냅니다. [^0-9]와 같으며, \d 의 반대라고 생각하면 됩니다.


\f

폼피드 문자입니다.


\n

줄바꿈 문자입니다.


\r

캐리지 리턴 문자입니다. ( 줄의 처음으로 가는 문자 )


\s

여러가지 공백 문자들을 포함한 문자입니다. ( \n, 공백, 폼피드 등 )


\S

공백 문자가 아닌 문자입니다.


\t

탭 문자입니다.


\v

수직 탭 문자입니다.


\w

영문 / 숫자 / _ 기호를 나타내는 문자입니다. [A-Za-z0-9_] 와 같습니다.


\W

영문 / 숫자 / _ 기호를 제외한 문자입니다.


\숫자

정규식에서 포획 괄호 안에 있던 내용 중 숫자 번째 항목을 이곳으로 가져옵니다. 예를 들어 /(jam) \1/ 로 검사할 시 "jam jam"은 일치, "jam jar"는 불일치인 것입니다. 전에 있던 괄호들 중 몇번째 괄호를 선택할지 정하는 것입니다.


\0

null 문자를 나타냅니다.


속성

속성들은 같이 쓰면 중첩될수 있습니다.

g

글로벌 옵션으로, replace 함수를 이용할때 모든 항목을 바꾼다거나 할 수 있습니다.


i

대소문자 구별을 하지 않게 합니다.


m

멀티라인 검색입니다.


y

끈끈한 검색이라고 합니다.



예제

1
2
let reg = (/#([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})/);
console.log(reg.exec("#AABBCC"));
cs

간단히, 문자열에서 #FFFFFF 식의 HEX 색상 코드를 두개씩 추출하는 예제입니다. 먼저 가장 앞에 있어야 할 #을 체크하기 위해 앞에 #이 들어가 있습니다. 그리고 그 뒤에는 [A-Fa-f0-9], 즉 HEX 문자열이 맞는지를 검사하는 녀석들을 만들어주고 그걸 {2}로 두개로 만들어 준 다음, 세 개의 포획 괄호에 묶여 있습니다. 총 3개가 들어가서 각각 2개씩 RGB를 떼어냅니다. 그렇게 떼어낸 RGB는 exec을 했을때 배열로 주어집니다.


배열의 1,2,3 번째 항목에 들어가 있는 것을 볼 수 있습니다.


1
2
3
4
let reg = (/#([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})([A-Fa-f0-9]{2})/);
let result = reg.exec("#AABBCC");
 
console.log("R: "+parseInt(result[1],16)+" G: "+parseInt(result[2],16)+" B: "+parseInt(result[3],16));
cs

조금 더 발전시키면 위같은 코드로 RGB를 추출할수도 있겠죠. substring같은 함수를 이용해서 코드를 뽑는 것보다는 훨씬 간단하지 않나요?




지금까지 정규식에 대해서 알아보았습니다. 처음 접할 때는 상당히 어렵지만, 배우고 나면 코드가 간결해지고 편리해지니 꼭 잘 공부해둬야 되겠습니다. 그럼 이번 글은 여기서 마치도록 하겠습니다. 이만.