티스토리 뷰
정규 표현식은 문자열에서 문자 결합을 일치시키는데 사용되는 패턴이다. JavaScript에서, 정규 표현식은 또한 객체이다. 이들 패턴들은 RegExp의 exec와 test 메소드들, 그리고 String의 match, replace, search, split 메소드들과 함께 사용된다. 이 章은 자바스크립 정규 표현식(JavaScript regular expressions)을 설명한다
JavaScript 1.1과 이전 버전.
정규 표현식은 JavaScript 1.1과 그 이전 버전에서는 사용할 수 없다.
정규 표현식 생성
(Creating a Regular Expression)
정규 표현식은 두 방법 중 하나를 사용하면 생성된다:
- 객체 초기화(object initializer) 사용, 다음처럼:
re = /ab+c/
- 객체 초기화(Object initializer)는 해당 스크립이 평가될 때 그 정규 표현식에 대한 컴파일을 지원한다. 정규 표현식이 상수로 남아 지속될 경우, 이를 사용하면 보다 나은 실행을 할 수 있다. 객체 초기화(Object initializer)는 95 페이지의 "Using Object Initializers"에서 논의되고 있다.
- RegExp 객체의 생성자 함수 호출, 다음처럼:
re = new RegExp("ab+c")
- 생성자 함수를 사용하면 정규 표현식 실시간 컴파일을 지원한다. 정규 표현식 패턴이 추후 변경될 경우 또는 사용자 입력과 같은 다른 소스로부터 얻게 될 패턴인 경우 생성자 함수를 사용하라. 일단 정규 표현식을 정의하면, 그 정규 표현식이 스크립 전체를 통해 사용되거나 그 소스가 변경될 경우에 있어 효율적인 재활용을 위해 새로운 정규 표현식을 컴파일할 수 있는 compile 메소드를 사용할 수 있다.
정규 표현식 패턴 표현
(Writing a Regular Expression Pattern)
정규 표현식 패턴은 /abc/
와 같은 단순 문자나 /ab*c/
또는 /Chapter (d+).d*/
와 같은 특수 문자의 조합으로 구성된다. 마지막 예는 괄호를 포함하고 있는데, 이는 마치 기억 장치처럼 사용된다. 패턴의 이 부분과의 일치는, 64 페이지의 "Using Parenthesized Substring Matches"에서 설명되고 있는 것처럼 후에 사용되기 위해 기억된다
단순 패턴(Simple Patterns) 사용하기
단순 패턴은 찾고자 하는 직접적인 일치의 문자들로 구성된다. 예컨대, /abc/
패턴은 오로지 문자들 'abc'가 순서있게 정확히 발생하는 문자열 안의 문자 조합과 일치한다. 이 일치는 문자열 "Hi, do you know your abc's?"과 "The latest airplane designs evolved from slabcraft"에서 성공적이다. 이들 두 경우는 substring인 'abc'와 일치한다. substring인 'abc'를 포함하지 않으므로 문자열 "Grab crab"에서는 일치가 없다.
특수 문자(Special Characters) 사용하기
직접적인 일치보다 많은 어떤 것을 요구하는 일치 검색시, 하나 또는 그 이상의 'b' 또는 공백(whitespace) 찾기처럼, 패턴은 특수 문자를 포함한다. 예컨대 패턴 /ab*c/
는 0회 또는 그 이상의 'b'가 뒤따르고 (*는 선행 문자가 0 또는 그 이상의 발생을 의미한다) 'c'가 그 바로 뒤를 따르는 단일 'a'가 있는 어떤 문자 조합과 일치한다. "cbbabbbbcdebc" 문자열에서 이 패턴은 substring으로는 'abbbbc'와 일치한다.
다음 표는 정규 표현식에서 사용될 수 있는 특수 문자들의 완전한 리스트와 설명을 제공한다.
Character | Meaning |
---|---|
다음 중 하나:
/b/ 는 문자 'b'와 일치한다. b 앞에 역슬러쉬를 두면, 이는 /b/ 처럼 사용한다, 그 문자는 단어 경계 일치 수단으로 특수하게 된다.
* 는 일치되어야 할 선행 문자의 0 또는 그 이상의 발생을 의미하는 특수문자이다; 예컨대, /a*/ 는 0회 또는 그 이상의 a들과 일치한다. * 를 리터럴로 일치시키려면, 역슬러쉬를 그 앞에 둔다; 예컨대, /a*/ 는 'a*'와 일치한다. | |
^ | 입력 또는 라인의 시작과 일치.
예컨대, |
$ | 입력 또는 라인의 끝과 일치.
예컨대, |
* | 선행 문자의 0 또는 그 이상의 회와 일치.
예컨대, |
+ | 선행 문자의 1 또는 그 이상의 회와 일치. {1,} 와 동등하다.
예컨대, |
? | 선행 문자의 0 또는 1 회와 일치.
예컨대, |
. | (십진수) 새로운 라인을 여는 문자를 제외한 어느 단일 문자와의 일치.
예컨대, |
(x) | 'x'와 일치하고 이 일치를 기억한다.
예컨대, |
x|y | 'x' 또는 'y'와 일치.
예컨대, |
{n} | n 이 양의 정수인 곳에서. 선행문자의 n 회 발생과 정확히 일치한다.
예컨대, |
{n,} | n 이 양의 정수인 곳에서. 선행문자의 적어도 n 회 발생과 일치한다.
예컨대, |
{n,m} | n 과 m 이 양의 정수인 곳에서. 선행문자의 최소 n 최대 m 회 발생과 일치한다.
예컨대, |
[xyz] | 문자 셑. 묶여진 문자들 중 어느 하나와의 일치. 하이픈을 사용하면 문자들의 범위를 지정할 수 있다.
예컨대, |
[^xyz] | 부정되거나 보완적 의미의 문자 셑. 즉, 이는 []에 묶여지지 않은 것이라면 어떠한 것과도 일치한다. 하이픈을 사용하면 문자들의 범위를 지정할 수 있다.
예컨대, |
[b] | backspace와 일치. (b 와 혼돈하지 말 것.) |
b | 공간 또는 새로운 라인을 여는 문자 같은 단어 경계와 일치. ([b] 와 혼돈하지 말 것.)
예컨대, |
B | 非 단어 경계와 일치.
예컨대, |
cX | X가 제어 문자(control character)인 곳에서. 문자열에 있는 제어문자와 일치.
예컨대, |
d | 수치 문자와 일치. [0-9] 와 동등하다.
예컨대, |
D | 非-수치 문자(non-digit character) 그 어떠한 것과도 일치. [^0-9] 와 동등하다.
예컨대, |
f | form-feed와 일치. |
n | linefeed와 일치. |
r | 캐리지 반환(carriage return)과 일치. |
s | 단일 공간문자(single white space character)와 일치, space, tab, form feed, line feed를 포함한다. [ fnrtv] 와 동등하다.
예컨대, |
S | 공간(white space)이 아닌 단일 문자와 일치. [^ fnrtv] 와 동등하다.
예컨대, |
t | 탭(tab)과 일치 |
v | 수직 탭(vertical tab)과 일치. |
w | underscore를 포함하고 있는 문자와 숫자의 혼용(alphanumeric) 문자와의 일치. [A-Za-z0-9_] 와 동등하다.
예컨대, |
W | 非-단어 문자(non-word character)와의 일치. [^A-Za-z0-9_] 와 동등하다.
예컨대, |
n | n이 양의 정수인 곳에서. 정규 표현식에 삽입되어 있는 n과 일치하는 마지막 substring에 대한 역참조(좌측 삽입어구를 카운트하면서).
예컨대, Note: 좌측 삽입어구의 수치가 n에 지정된 수치보다 작을 경우, n는 다음 열에서 설명하는 octal escape로 취급된다. |
ooctal xhex | ooctal이 8진수 escape 값이거나 또는 xhex가 16진수 escape 값인 곳에서. 정규 표현식에 ASCII 코드들을 삽입(embed)할 수 있다. |
삽입어구(Parentheses) 사용하기
정규 표현식 패턴의 어느 부분을 둘러싸는 삽입어구는 일치된 substring의 그 부분을 기억되게 하는 원인이 된다. 한번 기억되면 그 substring은, 64 페이지의 "Using Parenthesized Substring Matches"에서 설명고 있는 것처럼, 다른 용도로 재 호출될 수 있다.
예컨대, 패턴 /Chapter (d+).d*/
은 이스케이프되어 특수하게 된 문자를 추가 삽입하여 기억되어야 할 그 부분을 가리킨다. 이는 규칙대로 정확히 문자들인 'Chapter '와 일치하는데, 이 문자들 뒤를 하나 또는 그 이상의 수치 문자(d
는 수치문자를 의미하고 +
는 1 또는 그 이상의 회를 의미한다)가 뒤따르고, 소수점(이는 그 자체에서는 특수문자이다; 반드시 리터럴 문자 '.'를 찾아야 하는 패턴을 의미하는 를 가진 소수점을 우선하고 있으므로)이 뒤따르며, 0 또는 그 이상의 회의 수치 문자(d
는 수치 문자를 의미하고, *
는 0 또는 그 이상의 회를 의미한다)가 뒤따른다. 추가하여, 삽입어구들은 처음으로 일치된 수치문자를 기억하는데 사용되고 있다.
이 패턴은 "Open Chapter 4.3, paragraph 6"에서 발견되고 '4'가 기억된다. 이 패턴은 "Chapter 3 and 4"에서 발견되지 않는데, 문자열이 '3' 뒤에 종지부를 가지고 있지 않기 때문이다.
정규 표현식 사용
(Working With Regular Expressions)
exec |
문자열에서 일치를 위해 검색을 실행하는 |
test |
문자열에서 일치를 위해 테스트하는 |
match |
문자열에서 일치를 위해 검색을 실행하는 |
search |
문자열에서 일치를 위해 테스트하는 |
replace |
문자열에서 일치를 위해 검색을 실행하여 일치된 substring을 대체 substring으로 바꾸는 |
split |
정규 표현식 또는 지정된(fixed) 문자열을 사용하여 문자열을 substring들의 배열로 깨뜨리는 |
문자열에서 패턴의 발견여부를 확인하고자 할 경우, test
또는 search
를 사용하라;
더 많은 정보를 얻고자 한다면(실행속도는 느리다) exec
또는 match
메소드를 사용하라.
exec
또는 match
를 사용하여 일치가 성공하면, 이들 메소드들은 배열을 반환하고 관련한 정규 표현식 객체와 사전 정의된 정규 표현식 객체인 RegExp
의 특성들을 업데이트한다.
일치가 실패하면, exec
메소드는 null
(이는 false
로 전환한다)을 반환한다.
다음 예에서, 스크립은 문자열에서 일치를 찾기 위해 exec
메소드들 사용하고 있다.
<SCRIPT LANGUAGE="JavaScript1.2">
myRe=/d(b+)d/g;
myArray = myRe.exec("cdbbdbsbz");
</SCRIPT>
정규 표현식의 특성들에 접근할 필요가 없을 경우, myArray
생성의 대체 방법은 다음 스크립이다:
<SCRIPT LANGUAGE="JavaScript1.2">
myArray = /d(b+)d/g.exec("cdbbdbsbz");
</SCRIPT>
정규 표현식을 재 컴파일하기를 원할 경우, 또 다른 선택은 다음 스크립이다:
<SCRIPT LANGUAGE="JavaScript1.2">
myRe= new RegExp ("d(b+)d", "g:);
myArray = myRe.exec("cdbbdbsbz");
</SCRIPT>
이들 스크립을 사용하면, 일치는 성공하여 배열을 반환하고 아래 표에 보여지고 있는 특성들을 업데이트한다.
Object | Property or index | Description | In this example |
---|---|---|---|
myArray | 일치된 문자열과 기억된 모든 substring들 | ["dbbd", "bb"]
| |
index | input 문자열에서의 일치의 색인으로 0부터 시작한다 | 1
| |
input | 원래의 문자열 | "cdbbdbsbz"
| |
[0] | 최후로 일치된 문자들 | "dbbd"
| |
myRe | lastIndex | 다음 일치가 시작하는 색인.(정규 표현식이 오직 66 페이지 "Executing a Global Search and Ignoring Case"에서 설명하고 있는 g 옵션을 사용해야 이 특성은 설정된다).
| 5
|
source | 패턴의 텍스트 | "d(b+)d"
| |
RegExp | lastMatch | 최후로 일치된 문자들 | "dbbd"
|
leftContext | 가장 최근 일치에 선행하는 substring | "c"
| |
rightContext | 가장 최근 일치를 뒤따르는 substring | "bsbz" |
RegExp.leftContext와 RegExp.rightContext은 또 다른 값들로 부터 계산될 수 있다.
RegExp.leftContext은 다음과 동등하다:
myArray.input.substring(0, myArray.index)
그리고 RegExp.rightContext
은 다음과 동등하다:
myArray.input.substring(myArray.index + myArray[0].length)
이 예의 두번째 양식에서 보여지는 것처럼, 변수에 할당하지 않고 객체 initializer로 생성된 정규 표현식을 사용할 수 있다. 하지만 이렇게 할 경우 매번 새로운 정규 표현이 발생한다. 이러한 이유로 변수에 할당하지 않고 이 양식을 사용하면 해당 정규 표현에 연속적으로 접근할 수 없다. 예컨대, 다음 스크립을 가정하자:
<SCRIPT LANGUAGE="JavaScript1.2">
myRe=/d(b+)d/g;
myArray = myRe.exec("cdbbdbsbz");
document.writeln("The value of lastIndex is " + myRe.lastIndex);
</SCRIPT>
이 스크립이 디스플레이하는 것은:
The value of lastIndex is 5
하지만 다음 스크립의 경우:
<SCRIPT LANGUAGE="JavaScript1.2">
myArray = /d(b+)d/g.exec("cdbbdbsbz");
document.writeln("The value of lastIndex is " + /d(b+)d/g.lastIndex);
</SCRIPT>
이의 디스플레이는:
The value of lastIndex is 0
위 두 문장에 있는 /d(b+)d/g
의 발생은 서로 다른 정규 표현 객체들이므로 그들의 lastIndex
특성에 있어 다른 값들을 가진다. 객체 initializer로 생성된 정규 표현의 특성들에 접근하려면, 먼저 이를 변수에 할당해야 한다.
삽입된 Substring 일치 사용하기
(Using Parenthesized Substring Matches)
정규 표현 패턴에 삽입어구들을 포함시키면 일치하는 submatch가 기억된다. 예컨대, /a(b)c/
는 문자들 'abc'와 일치하고 'b'를 기억한다. 삽입된 이들 substring 일치를 재호출하려면, RegExp
특성들 $1
, ..., $9
또는 Array
요소들 [1]
, ..., [n]
를 사용한다.
substring의 삽입 가능 수는 무제한이다. 사전 정의된 RegExp
는 마지막 9까지 유지하고 반환된 배열은 발견된 모든 것을 유지한다. 다음 예는 삽입된 substring 일치의 사용 방법을 설명하고 있다.
Example 1.
아래 스크립은 replace
메소드를 사용하여 문자열에서 단어들을 변경 연결한다. 텍스트를 재 배치하기 위해 스크립은 $1
와 $2
특성들 값을 사용한다.
<SCRIPT LANGUAGE="JavaScript1.2">
re = /(w+)s(w+)/;
str = "John Smith";
newstr = str.replace(re, "$2, $1");
document.write(newstr)
</SCRIPT>
프린트 결과는 "Smith, John".
Example 2.
아래 예에서, RegExp.input
는 변경의 이벤트에 의해 설정된다. getInfo
함수에서, exec
메소드는 RegExp.input
의 값을 그 인수로 사용한다. RegExp
는 자신의 $
특성들로 가장되어 있어야 함에 주의하라(이들은 재배치 문자열 외부에 나타나기 때문이다). (Example 3은 더욱 비밀스럽기는 하지만, 동일한 것을 성취함에 있어 훨씬 효율적이다)
<HTML>
<SCRIPT LANGUAGE="JavaScript1.2">
function getInfo(){
re = /(w+)s(d+)/
re.exec();
window.alert(RegExp.$1 + ", your age is " + RegExp.$2);
}
</SCRIPT>
성과 나이를 입력한 후 Enter.
<FORM>
<INPUT TYPE="text" NAME="NameAge" onChange="getInfo(this);">
</FORM>
</HTML>
Example 3.
다음예는 Example 2와 유사하다. 이 예는 RegExp.$1
와 RegExp.$2
대신 배열을 생성하여 a[1]
와 a[2]
를 사용한다. 이는 또한 exec
메소드의 손쉬운 사용 방법이다.
<HTML>
<SCRIPT LANGUAGE="JavaScript1.2">
function getInfo(){
a = /(w+)s(d+)/();
window.alert(a[1] + ", your age is " + a[2]);
}
</SCRIPT>
성과 나이를 입력한 후 Enter.
<FORM>
<INPUT TYPE="text" NAME="NameAge" onChange="getInfo(this);">
</FORM>
</HTML>
Global Search를 실행하여 Case 무시하기
(Executing a Global Search and Ignoring Case)
정규 표현식은 global과 감지할 수 없는 검색 case를 허용하는 두 선택적 flag들을 가지고 있다.
g
flag를 사용하면 global 검색임을 나타낸다.
i
flag를 사용하면 감지할 수 없는 case 검색임을 가리킨다.
이들 flag들은 따로 따로 또는 어느 한쪽의 순서에 따라 혼합되어 사용될 수 있으며,
정규 표현식의 부분에 속한다.
정규 표현식에 flag를 포함하려면, 이 구문을 사용한다:
re = /pattern/[g|i|gi]
re = new RegExp("pattern", ['g'|'i'|'gi'])
flag들(i
와g
)은 정규 표현식의 구성 요소임에 주의하라. 이들은 이후에 추가되거나 제거될 수 없다.
예컨대,re = /w+s/g
는 space가 뒤따르는 하나 또는 그 이상의 문자들을 찾는
정규 표현식을 생성하고, 문자열을 통해 이러한 조합을 찾는다.
<SCRIPT LANGUAGE="JavaScript1.2">
re = /w+s/g;
str = "fee fi fo fum";
myArray = str.match(re);
document.write(myArray);
</SCRIPT>
이는 ["fee ", "fi ", "fo "]를 디스플레이한다. 이 예에서, 아래 라인을:
re = /w+s/g;
다음으로 대체할 수 있으며:
re = new RegExp("\w+\s", "g");
동일한 결과를 얻는다.
입력 문자열에서 순서 변경하기(Changing the Order in an Input String)
다음 예는 정규 표현식의 양식과string.split()
및string.replace()
사용을 묘사하고 있다.
이는 blank들, tab들 그리고 정확히 하나의 세미콜론에 의해 분리되어 있는 (姓이 선두인) 성과 이름들을
정돈되지 않은 상태로 포함하고 있는 입력 문자열을 정돈한다.
결국, 이는 (이름을 선두로) 성과 이름의 순서를 재 배치하여 리스트로 분류한다.
<SCRIPT LANGUAGE="JavaScript1.2">
// 이 성과 이름 문자열은 여러 space들과 tab들을 포함하고 있으며,
// 성과 이름 사이에 여러 space들을 갖고 있을 것이다.
names = new String ( "Harry Trump ;Fred Barney; Helen Rigby ;
Bill Abel ;Chris Hand ")
document.write ("---------- Original String" + "<BR>" + "<BR>")
document.write (names + "<BR>" + "<BR>")
// 두 정규 표현식과 저장용 배열을 준비한다.
// 문자열을 배열 요소들로 분리한다.
// 패턴: white space의 가능 다음 세미콜론 다음 white space의 가능
pattern = /s*;s*/
// 위 패턴을 사용 이 문자열을 조각낸 후
// nameList 배열에 이 조각들을 저장한다
nameList = names.split (pattern)
// 새 패턴: 하나 또는 그 이상의 문자들 다음 space들 다음 문자들.
// 패턴의 부분들을 "기억하기" 위해 삽입어구들을 사용.
// 기억된 부분들은 이후 참조 조회된다.
pattern = /(w+)s+(w+)/
// 진행되는 동안 성과 이름들을 붙잡아 둘 새로운 배열.
bySurnameList = new Array;
// 성과 이름 배열을 디스플레이하고
// 이름을 선두로 하고 컴마로 분리된 성과 이름들로 새로운 배열을 거주시킨다(populate).
//
// replace 메소드는 패턴과 일치하는 어떤 것을 제거하고
// 이를 기억된 문자열로 재배치한다--두번째로 기억된 부분(second memorized portion)을
// 첫번째 기억된 부분이 comma space를 통해 뒤따른다.
//
// 변수들 $1와 $2는 이들 부분들을 참조한다
// 이들 부분들은 패턴을 일치시키는 동안 기억되었다.
document.write ("---------- After Split by Regular Expression" + "<BR>")
for ( i = 0; i < nameList.length; i++) {
document.write (nameList[i] + "<BR>")
bySurnameList[i] = nameList[i].replace (pattern, "$2, $1")
}
// 새로운 배열을 디스플레이한다.
document.write ("---------- Names Reversed" + "<BR>")
for ( i = 0; i < bySurnameList.length; i++) {
document.write (bySurnameList[i] + "<BR>")
}
// 이름으로 분류한 후 분류된 배열을 디스플레이한다.
bySurnameList.sort()
document.write ("---------- Sorted" + "<BR>")
for ( i = 0; i < bySurnameList.length; i++) {
document.write (bySurnameList[i] + "<BR>")
}
document.write ("---------- End" + "<BR>")
</SCRIPT>
입력 검증용으로 특수 문자들 사용하기
(Using Special Characters to Verify Input)
다음 예에서, 사용자는 전화번호를 입력한다.
사용자가 Enter를 누르면, 이 스크립은 그 번호의 유효성을 체크한다.
그 번호가 유효하면(정규 표현식에 의해 지정된 연속된 문자들과 일치시켜),
스크립은 사용자에게 감사의 윈도우를 보여주고 그 번호를 인증한다.
유효하지 않으면, 사용자에게 전화번호가 유효하지 않음을 알리는 윈도우를 보여준다.
정규 표현식은 zero 또는 하나의 열린 삽입어구
(?
, 3 개의 아라비아 숫자d{3}
가 뒤따르고,
zero 또는 하나의 닫힌 삽입어구가 뒤따르는)?
를 찾으며, 뒤를 하나의 dash, forward slash,
또는 십진수가 뒤따르며, 발견되면 문자([-/.])
를 기억하며, 뒤를 3 개의 아라비아 숫자d{3}
가
뒤따르고, dash, forward slash, 또는 십진수1
로 일치된 기억이 뒤따르며,
4 개의 아라비아 숫자d{4}
가 뒤를 잇고 있다.
사용자가 Enter를 누름으로써 활성화된 변경 이벤트는
RegExp.input
의 값을 설정한다.
<HTML>
<SCRIPT LANGUAGE = "JavaScript1.2">re = /(?d{3})?([-/.])d{3}1d{4}/function testInfo() {
OK = re.exec()
if (!OK)
window.alert (RegExp.input +
" isn't a phone number with area code!")
else
window.alert ("Thanks, your phone number is " + OK[0])
}</SCRIPT>귀하의 전화번호 (지역코드와 함께)를 입력한 후 Enter를 누르세요.
<FORM>
<INPUT TYPE="text" NAME="Phone" onChange="testInfo(this);">
</FORM></HTML>
'웹개발 > Javascript' 카테고리의 다른 글
Javascript Switch문을 바꿔서 표현 (0) | 2011.01.08 |
---|---|
Javascript 재 입문 (0) | 2011.01.08 |
자바스크립트 시간 계산 샘플 (1) | 2010.12.20 |
Understanding JavaScript Prototypes. (0) | 2010.12.14 |
Javascript Namespace 정리 (0) | 2010.12.14 |