1. 정규 표현식(Regular Expression)이란?
정규 표현식이란 특정한 형태의 문자나 문자열을 추출하는 규칙을 일정한 패턴 표현을 이용해 나타낸 식을 말한다. javascript에서는 정규 표현식 자체를 객체로 구현하기 때문에 regExp 형식의 객체를 만들어야 한다.
연습) 정규 효현식 객체 만들기
- var reg = new regExp("패턴문자열", "한정자"); var reg=new regExp("is", "g"); <- 다음 설명 참조;
- var reg = /패턴문자열/한정자; var reg = /is/g; <- 문자열을 나타내는 "가 없는 점에 주의
- var reg = "/패턴문자열/한정자"; (x) <- 정규 표현식 객체가 아닌 문자열 객체를 생성
- var spat = "/패턴문자열/한정자"; var reg = new regExp(spat); (o) <- 문자열을 정규 표형식 생성자의 인수롤 전달
- var reg = eval("/패턴문자열/한정자"); (o) <- eval 함수는 문자열 내의 내용을 javascript 명령으로 보기 때문에 ok;
2. 어떤 규칙을 만들 것이가?
정규 표현식은 추출하려는 패턴 + 이 패턴이 적용되는 범위 및 조건을 한정하는 한정자의 가지 요소로 구성된다. 이를 일반 언어로 사용하면 다음과 같이 표현할 수 있다.
예 1) "@"라는 문자(패턴)이 존재하는가?
예 2) "@"라는 문자 다음에 최소한 1글자 이상의 알파벳과 "."이 존재하는가? 단, 대소문자는 구분하지 않는다.
위 예2)에서 대소문자를 구분하지 않는다는 조건을 범위 한정자(modifier)라고 한다.
3. 언제 어떻게 써먹지?
정규 표현식은 문자열을 찾기 위한 목적이므로 당연히 이를 사용하기 위해서는 대상 문자열이 존재해야 한다. javascript는 문자열을 String 객체로 구현하기 때문에 문자열에 이 정규 표현식을 이용하는 메서드를 가지고 있다. 대표적인 메서드로는
search(), match(), replace()가 있다.
각 메서드는 모두 메서드 인자로 정규 표현식 객체를 받는다. 예를 들어 다음과 같은 정규 표현식이 있다면
var reg = new regExp("is", "g"); <- 전체(g)범위에서 "is"라는 문자열 패턴을 규정한다.
아래와 같이 문자열 객체를 이용해 정규 표현식을 써먹을 수 있다.
var ret = "This is a test".search(reg); <- ""로 둘러싸인 문자열은 문자열 객체로 해석된다.
var str = "This is a test"; var ret = str.match(reg); <- "문자열 객체를 str이라는 변수에 저장한 후 사용한다.
var str = new String("This is a test"); var ret = str.replace(reg, "are"); <- 명시적으로 문자열 객체를 생성한다.
위 세가지 방법 모두 정상적으로 동작한다. 취향에 맞게 사용하면 된다.
4. 일단 만만한 한정자부터 알아보자
자바스크립트의 대표적인 한정자는 다음 세 가지가 있다.
i : ignore case (대소문자를 무시한다)
g: global(몽땅 다 찾는다. 이것을 지정하지 않으면 맨 처음 패턴이 발견되면 더이상 찾지 않는다.)
m: multiline (여러 행에 걸쳐 찾는다. 이건 예제를 통해 이해하는게 빠르다.)
5. 아주 간단한 패턴부터 연습해 보자.
- "is" 라는 문자열이 있는가? => 이건 그냥 "is"라고 쓰면 된다.
- i또는 s라는 문자가 있는가? => [is] : 대괄호로 묶으면 대괄호내의 한 글자가 해당된다.
- i또는 s를 제외한 문자를 찾는다 => [^is]
- 거의 쓸일이 없지만 문자의 범위를 지정할 수도 있다. : [a-g] => abcdefg 중의 한 문자를 대상으로 한다.
- 단어를 택일하고 싶은 경우 괄호와 파이프라인 기호(|)를 이용한다.
is 또는 are가 있는가? => (is|are)
6. 와일드 캐릭터
DOS 시절에 Wild Charactor 문자를 사용한 사람을 잘 알 것이다. 와일드 캐릭터는 대표 문자라고 표현할 수 있는데 한 글자만 지정하는 경우와 복수 문자를 지정하는 경우로 대표된다. 정규 표현식에서는 이를 보다 세분화해서 표현하고 있다.
= 한글자 대응 대표 문자 . (점) DOS 시절의 ?에 해당한다.
연습 : 문자열에서 h로 시작하고 t로 끝나는데 중간에 한 글자가 있는 패턴을 정의해 보자 : <- h.t
= 한단어 대응 대표 문자 \w
연습 : "This is bad!" 에서 단어로 구성된 모든 문자는 ? -> [This],[is],[bad]
이 패턴의 결과는 단어를 구성한 모든 문자를 반환하기 때문에 T,h,i,s,i,s,b,a,d가 된다.
참고 : 대개 단어 전체를 결과에 포함시키는 경우가 많은데 이 경우 뒤에 나타나는 빈도 지정 표현을 사용한다. 이 경우 단어를 리턴하고 싶면 +(1회 이상)를 지정해 \w+를 지정한다.
= 단어어 구성에 포함되지 않는 문자 \W
연습 : "This is bad!" 에서 단어 구성에서 제외된 문자는 ? -> [ ],[ ],[!]
이 패턴의 결과는 단어를 구성한 모든 문자를 반환하기 때문에 , ,!가 된다.
= 위 내용을 이해 했으면 다음과 같은 패턴 정도는 스스로 유추할 수 있을 것이다.
\d : 숫자문자 \D 숫자아닌 문자, \s : 공백문자 \S: 공백아닌 문자
= 단어의 시작 \b문자열 : 문자열로 시작하는 단어 , \B문자열 : 문자열로 시작하지 않는 단어
연습 : This is a Test!에서 T로 시작하는 단어는? This, Test => \bT 로 지정한다. 리턴되는 결과는 T, T
7. 발생 빈도 지정 표현식 ?+*
앞 표현식과 연관해서 앞문자가 몇번 반복되는지 나타내는 표현식으로 ?는 0..1번 +는 1번 이상 *는 0번 이상을 나타낸다.
ao? ==> a(ok) ao(ok) aoo(no)
ao+ ==> a(no) ao(ok) aoo(ok)
ao* ==> a(ok) ao(ok) aoo(ok)
[abc]o? => a,b,c중 한 문자와 o가 0또는 1회 나타나는 경우 ok => ao(ok) aoo(no) a(ok) b(ok) do(no)
[abc]o+ => a,b,c중 한 문자와 o가 1회 이상 나타나는 경우 ok => ao(ok) aoo(ok) a(no) b(no) do(no)
[abc]o* => a,b,c중 한 문자와 o가 0또는 이상 나타나는 경우 ok => ao(ok) aoo(ok) a(ok) b(ok) do(ok)
반복 횟수를 명시하고자 할때는 중괄호를 사용해 다음과 같이 표현한다.
{n}은 n번, {n1, n2}는 n1부터 n2까지 {n,}는 n번 이상
따라서 ? === {0,1} + === {1,} * === {0,}으로 대치할 수 있다.
8. 연습문제
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/