반응형

정규식(Regular Expressions)


 

정규식은 문자열에 포함된 문자 조합을 찾기 위해 사용되는 패턴입니다. 코드를 간략하게 만들 수 있으나, 가독성이 떨어질 수 있습니다.

RegExp의 exec, test 메소드와 String의 match, replace, search, split 메소드와 함께 사용됩니다.

 

 

1. 정규식

두가지 방법으로 정규식을 만들 수 있습니다.

 

정규식 패턴이 계속 지속될 경우

1

var re = /ab+c/;

정규식이 계속 지속 될 경우 위와 같은 리터럴 방법을 사용하는 것이 좋습니다.

 

 

정규식 패턴이 변경되는 경우

1

var re = new RegExp("ab+c");

정규식 패턴이 바뀌는 경우, 생성자 함수를 사용하여 동적으로 정규식을 만들 수 있습니다.

 

 

2. 정규식 패턴 만들기

정규식 패턴은 /abc/와 같이 단순한 문자열로 만들 수 있습니다. 또한 /ab*c/ 또는 /(\d+)\.=d%/ 와 같이 특수 문자와 단순 문자열의 조합으로 정규식 패턴을 만들 수 있습니다.

 

단순 문자열 패턴

단순 문자열 패턴은 직접 찾고자 하는 문자들로 구성됩니다.

예를 들어, /abc/는 this is abc의 abc에 매칭됩니다.

1

/abc/.exec("this is abc");

단순 문자열 패턴

 

하지만 /abc/는 this is ab c에 매칭 되지 않습니다.

1

/abc/.exec("this is ab c");

단순 문자열 패턴

 

 

특수문자를 사용한 패턴

하나 이상의 b를 찾거나, 단순 문자열 패턴보다 다양한 문자열을 찾기 위해 사용됩니다.

예를 들어, /ab*c/ 패턴은 'a' 뒤에 0개 이상의 'b'와 바로 뒤에 'c'가 있는 문자열을 찾습니다. /ab*c/는 abbbbbbbbbce에서 abbbbbbbbbc와 매칭됩니다.

1

/ab*c/.exec("this is abbbbbbbbbce");

특수 문자를 사용한 패턴

 

정규식에서의 특수문자

문자 의미 
\ 1. 단순문자 앞에 \

단순문자 앞에 \는 앞에 있는 단순문자를 단순문자로 해석되지 않고, 다른 의미로 해석되어집니다.

 

/a\d/는 단순 ad와 매칭되지 않습니다. \d는 새로운 의미를 가지게 됩니다. (\d는 0부터 9까지의 숫자와 매칭됩니다.)

 

단순문자 앞에 \

2. 특수문자 앞에 \

특수문자 앞에 \는 앞에 있는 특수문자를 단순문자로 해석합니다.

 

/a\*/는 aaaaaaa와 매칭되지 않습니다. \*은 단순문자 *로 해석됩니다. (특수문자 *은 앞 문자가 0개 이상일 경우 매칭됩니다.)

 

특수문자 앞에 \

^

입력의 시작 문자열에 매칭됩니다.

Multi-line 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자 바로 다음 문자에도 매칭됩니다.

 

/^A/는 "an A"와 매칭되지 않습니다. 하지만 "An E"와는 첫번째 'A'와 매칭됩니다.

 

특수문자 ^ 패턴

 

^는 문자셋([abc]) 패턴의 첫글자로 쓰인다면, 다른 의미를 가집니다. ([^abc]는 위에 언급한 내용되 다른 의미를 가짐)

$

입력의 끝 문자열에 매칭됩니다.

Multi-line 플래그가 참으로 설정되어 있다면, 줄 바꿈 문자 바로 전 문자에도 매칭됩니다.

 

/$t/는 eater에 매칭되지 않지만, eat의 마지막 문자 t에 매칭됩니다.

 

특수문자 $ 패턴

*

0번 이상 반복되는 문자열에 매칭됩니다. {0, }와 동일합니다.

 

/bo*/은 "A ghost booooed"의 "boooo"과 매칭됩니다.

/bo*/은 "A bird warbled"의 'b'에 매칭됩니다.

하지만, /bo*/은 "A goat grunted"와는 매칭되지 않습니다.

 

특수문자 * 패턴

 

/o*/은 "abcd"와 동일한 문자를 가지고 있지 않습니다. 하지만, 특수문자 *의 의미는 0번 이상 반복되는 문자열에 매칭되기 때문에, 동일한 문자가 없더라도 매칭되는 결과를 확인 할 수 있습니다.

 

특수문자 * 패턴

+

1번 이상 반복되는 문자열에 매칭됩니다. {1, }과 동일합니다.

 

/a+/는 "candy"의 'a'에 매칭됩니다.

/a+/는 "caaaaaaandy"의 "aaaaaaa"와 매칭됩니다.

하지만, /a+/는 "cndy"와는 매칭되지 않습니다.

 

특수문자 + 패턴

?

0~1번 반복되는 문자열에 매칭됩니다. {0, 1}과 동일합니다.

 

/e?le?/은 'e'가 0~1번 반복 후, 'l'이 온후 'e'가 0~번 반복된 문자열을 찾습니다.

/e?le?/은 "angel"의 "el"에 매칭됩니다.

/e?le?/은 "oslo"의 'l'에 매칭됩니다.

 

특수문자 ? 패턴

 

*, +, ?, {} 패턴은 가능 한 많은 문자열을 매칭시킵니다.

*, +, ?, {} 패턴 뒤에 ? 패턴을 사용하면, 가능한 가장 적은 문자열을 매칭시킵니다.

/\d+/는 "123abc"에 "123"과  매칭됩니다.

하지만, /\d+?/의 경우는 "123abc"에 '1'과만 매칭됩니다.

 

*, +, ?, {} 패턴 뒤에 ? 패턴을 사용

 

x(?=y)와 x(!?y)와 같이 검증에서도 사용됩니다.

.

다음 줄 문자(개행 문자)를 제외한 문자열에 매칭됩니다.

 

/.n/은 "an apple"에 "an"에 매칭됩니다.

하지만 /.n/은 "nay"와는 매칭되지 않습니다.

 

특수문자 . 패턴

(x)

'x'에 일치하고 일치한 것을 기억합니다. 괄호는 포획 괄호(capturing parentheses)라고 합니다.

 

/(foo) (bar)/은 "foo bar test"의 "foo bar"에 매칭됩니다. 또한 () 패턴으로 매칭된 값이 기억되는 것을 확인 할 수 있습니다.

 

특수문자 () 패턴

(?:x)

'x'에 일치하지만 일치한 것을 기억하지 않습니다. 괄호는 비포획 괄호(non-capturing parentheses)라고 합니다.

 

/abc+/는 "abcabcabc"에 "abc"가 매칭됩니다. ('ab' 뒤에 오는 'c'의 1번 이상 반복되는 문자열을 매칭합니다.)

abc가 반복되는 것을 매칭하고 싶을 때 (?:x) 패턴을 사용할 수 있습니다.

/(?:abc)+/는 "abcabcabc"에 "abcabcabc"가 매칭됩니다. (abc 전체를 + 패턴으로 매칭하게 됩니다.)

 

특수문자 (?:x) 패턴

x(?=y)

'y'가 뒤따라오는 'x'에만 매칭됩니다. lookahead라고 불립니다.

 

/foo(?=bar)/는 "foobar"의 "foo"에 매칭됩니다.

/foo(?=bar|test)/는 "footest"의 "foo"에 매칭됩니다. (foo이 뒤따라오는 문자열이 bar 또는 test 일 경우 매칭됩니다.)

 

특수문자 x(?=y) 패턴

x(?!y)

'y'가 뒤따라 오지 않는 'x'에만 매칭됩니다. negated lookahead라고 불립니다.

 

/\d+(?!\.)/는 "3.141"에 "141"과 매칭됩니다. (소수점이 뒤따라오지 않는 숫자와 매칭됩니다.)

 

특수문자 x(?!y) 패턴

x|y

'x' 또는 'y'에 일치합니다.

 

/green|red/는 "green apple"의 "green"에 매칭됩니다.

/green|red/는 "red apple"의 "red"에 매칭됩니다.

 

특수문자 x_y 패턴

{n}

앞 문자가 n번 나타날 경우 매칭됩니다. (n은 양의 정수)

 

/a{2}/는 "candy"에는 매칭되지 않습니다.

/a{2}/는 "caandy"의 "aa"와 매칭됩니다.

/a{2}/는 "caaandy"는 처음으로 오는 "aa"와 매칭됩니다.

 

특수문자 {n} 패턴

{n,m}

n ~ m번 반복되는 문자열과 매칭됩니다. (m, m은 양의 정수, n <= m)

 

/a{1, 3}/는 "cndy"에는 매칭되지 않습니다.

/a{1, 3}/는 "caandy"의 "aa"와 매칭됩니다.

/a{1, 3}/는 "caaaaaaandy"의 처음으로 오는 "aaa"에 매칭됩니다.

 

특수문자 {n,m} 패턴

[xyz]

문자셋(Character set)을 말합니다.

점(.), 별표(*)와 같은 특수 문자는 문자셋에서는 단순 문자로 인식됩니다. 하이픈(-)을 이용하여 문자의 범위를 지정 할 수 있습니다.

 

/[a-d]/는 "brisket"의 'b'와 매칭됩니다.

/[a-z.]+/는 "test.i.ng"의 문자열 전체, "test.i.ng"과 매칭됩니다.

 

특수문자 [xyz] 패턴

[^xyz]

음의 문자셋(negated character set) 또는 보수 문자셋(complemented character set)을 말합니다.

[] 안에 있지 않은 문자열과 매칭됩니다. 문자셋과 동일하게 하이픈(-)을 이용하여 문자의 번위를 저정 할 수 있습니다.

 

/[^a-d]/는 "brisket"에서 처음으로 a부터 d까지의 문자에 포함되지 않는 'r'과 매칭됩니다.

/[^a-d]/는 "chop"의 'h'와 매칭됩니다.

 

특수문자 [^xyz] 패턴

[\b]

백스페이스와 매칭됩니다. 백스페이스 문자에 일치 시키려면 대괄호([])를 이용해야 합니다.

\b

단어의 경계를 말합니다.

 

/\bm/은 "moon"의 m과 매칭됩니다.

/oo\b/는 "moon"과 매칭되지 않습니다. (문자열의 끝이 o이 아니지 때문에)

/n\b/는 "moon"의 n과 매칭됩니다.

 

특수문자 \b 패턴

\B

단어의 경계가 아닌 곳을 말합니다.

 

/\B../은 "noonday"의 "oo"와 매칭됩니다.

 

특수문자 \B 패턴

\cX

 X는 A에서 Z까지 문자중 하나입니다. 문자열에서 컬트롤 문자와 매칭됩니다.

\d

숫자 문자와 매칭됩니다.

 

/\d"/는 "a1b"의 '1'에 매칭됩니다.

 

특수문자 \d 패턴

\D

숫자가 아닌 문자와 매칭됩니다. ([^0-9]와 동일)

 

/\D/는 "1a2"의 'a'에 매칭됩니다.

 

특수문자 \D 패턴

\f

폼피드(U+000C) 문자에 매칭됩니다.

\n

줄 바꿈(U+000A) 문자에 매칭됩니다.

\r

캐리지 리턴(U+000D) 문자에 매칭됩니다.

\s

스페이스, 탭, 폼피드, 불 바꿈 문자등을 포함한 하나의 공백 문자와 매칭됩니다.

([ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​-\u200a​\u2028\u2029\u202f\u205f​\u3000] 와 동일)

 

/\sbar/는 "foo bar"의 " bar"에 매칭됩니다.

 

특수문자 \s 패턴

\S

공백이 아닌 하나의 문자와 매칭됩니다.

([^ \f\n\r\t\v​\u00a0\u1680​\u180e\u2000​-\u200a​\u2028\u2029\u202f\u205f​\u3000] 와 동일)

 

/\S+/는 "foo bar"의 "foo"에 매칭됩니다. (가장 먼저 오는 공백아닌 문자열)

 

특수문자 \S 패턴

\t

탭(U+0009) 문자에 매칭됩니다.

\v

수직 탭(U+000B) 문자에 매칭됩니다.

\w

밑줄 문자를 포함한 영어, 숫자 문자에 매칭됩니다. ([A-Za-z0-9_] 와 동일)

 

/\w+/는 "apple"에 문자열 전체, "apple"과 매칭됩니다.

/\w+/는 "$5.28"에 '5'와 매칭됩니다.

/\w+/는 "3D."에 "3D"와 매칭됩니다.

 

특수문자 \w 패턴

\W

단어가 아닌 문자와 매칭됩니다. ([^A-Za-z0-9_] 와 동일)

 

/\W+/는 "3D."에 '.'과 매칭됩니다.

 

특수문자 \W 패턴

\n

정규식 안 n번 괄호의 최근 일치 부분의 역참조 입니다. (n은 양의 정수)

 

/(foo) (bar) \1 \2/은 "foo bar foo bar"에 "foo bar foo bar"이 매칭됩니다. (\n 패턴은 괄호로 기억된 값을 참조하고 있습니다.)

\1은 첫번째 괄호로 매칭된 foo 값을 나타내고, \2는 두번째 괄호로 매칭된 bar를 나타냅니다.

즉 /(foo) (bar) \1 \2/ 패턴은 /(foo) (bar) foo bar/ 패턴과 동일합니다.

 

특수문자 \n 패턴

\0

Null 문자와 매칭됩니다.

\xhh

코드가 hh(2개의 16진수)인 문자와 매칭됩니다.

\xhhhh

코드가 hhhh(4개의 16진수)인 문자와 매칭됩니다.

 

 

3. 정규식 사용하기

정규식은 ExgExp 메소드에 test, exec, String 메소드에 match, replace, search, split 메소드와 함께 사용됩니다.

 

ExgExp 메소드

 Method

 Description

 exec

매칭된 문자열을 찾기 위한 메소드입니다.

매칭된 문자열이 있다면 매칭된 값의 배열을 리턴하고, 매칭된 문자열이 없다면 null을 리턴합니다.

 test

매칭된 문자열이 있는지 확인하기 위한 메소드입니다.

매칭된 문자열이 있다면 ture를 리턴하고, 매칭된 문자열이 없다면 false를 리턴합니다.

 

매칭된 문자열이 있는지 확인하는 용도로 메소드를 사용한다면, exec 메소드는 느릴 수 있기 때문에 test 메소드를 사용하는 것이 좋습니다.

 

ExgExp 메소드로 아래와 같이 정규식을 사용할 수 있습니다.

1

var myArray = /d(b+)d/g.exec('cdbbdbsbz');

 

ExgExp 객체를 따로 저장하여, 정규식을 사용 할 수도 있습니다.

1

2

var myRe = /d(b+)d/g; // 또는, var myRe = new RegExp('d(b+)d', 'g');

var myArray = myRe.exec('cdbbdbsbz');

 

ExgExp 객체를 따로 저장하여 사용한다면, ExgExp 객체의 프로퍼티 사용이 가능해집니다.

위의 예제의 실행 결과와 myRe 객체, myArray 객체의 값은 아래와 같습니다.

 

myRe 객체, myArray 객체의 값

 

Object

Property or index

Description

In this example

myArray

 

매칭된 문자열과 기억된 부분 문자열

["abbd", "bb"]

index

매칭된 문자열 인덱스 (0부터 시작)

1

input

원래의 문자열

"cdbbdbsbz"

[0]

매칭된 문자열

"abbd"

myRe

lastIndex

다음 매칭을 시작할 인덱스

5

source

정규식 패턴

"d(b+)d"

 

 

String 메소드

Method

Description 

match

매칭된 문자열을 찾기 위한 메소드입니다.

매칭된 문자열이 있다면 매칭된 값의 배열을 리턴하고, 매칭된 문자열이 없다면 null을 리턴합니다.

search

매칭된 문자열이 있는지 확인하기 위한 메소드입니다.

매칭된 문자열이 있다면 매칭된 문자열의 인덱스를 리턴하고, 매칭된 문자열이 없다면 -1를 리턴합니다.

replace

매칭된 문자열을 찾아 매칭된 문자열을 변경하는 메소드입니다.

split

매칭된 문자열을 찾아 그 문자열을 기준으로 문자열을 나누는 메소드입니다. 

 

매칭된 문자열이 있는지 확인하는 용도로 메소드를 사용한다면, match 메소드는 느릴 수 있기 때문에 search 메소드를 사용하는 것이 좋습니다.

 

정규식의 () 패턴을 String 메소드의 replace등에 활용할 수 있습니다.

/a(b)c/는 "abc"와 매칭되고, 'b'를 기억합니다. 괄호와 매칭된 문자열을 불러오기 위해, 배열 [1], ..., [n]을 사용합니다.

1

2

3

var str = "abcde";

var myArray = str.match(/a(b)c(d)/);

console.log(myArray);

String 메소드의 () 정규식 패턴 사용하기

 

0번 배열에는 매칭된 값이 저장되기 때문에, 기억된 부분 문자열은 1번부터 시작됩니다.

 

다음 예는 replace 메소드를 이용한 예제입니다. 괄호에 일치하는 부분 문자열을 의미하는 $1(첫번째 괄호 값), $2(두번째 괄호 값)을 사용하였습니다.

1

2

3

4

var re = /(\w+)\s(\w+)/;

var str = "John Smith";

var newstr = str.replace(re, "$2, $1");

console.log(newstr);

String 메소드의 () 정규식 패턴 사용하기

 

$1, $2를 사용하여, 두 문자열을 스와핑하는 예제입니다.

 

 

4. 정규식의 플래그

정규식의 플래그는 4가지가 있습니다.

 

Flag

Description 

g

전역 검색

i

대소문자 구별 없이 검색

m

Multi-line 검색, 시작 혹은 끝 문자 탐색(^ and $)이 다중행에 적용되도록 합니다.

y

현재 위치에서 검색

 

정규식의 플래그 정의하기

다음과 같이 플래그를 사용하여 정규식을 만들 수 있습니다.

1

2

3

var re = /pattern/flasgs;

// 혹은

var re = new RegExp("pattern", "flags");

플래그는 정규식을 처음 정의 할 때, 설정해야 합니다. 그 이후의 플래그를 추가하거나 삭제할 수 없습니다.

 

 

정규식의 플래그 예제

g 플래그를 이용하여 전역 검색

1

2

3

4

var re = /\w+\s/g;

var str = 'fee fi fo fum';

var myArray = str.match(re);

console.log(myArray);

match에서 g 플래그

 

g 플래그를 이용하여 매칭되는 모든 문자열을 가져올 수 있습니다. 만약 g 플래그를 사용하지 않는다면 처음으로 매칭되는 값만을 가져오게 됩니다.

1

2

3

4

var re = /\w+\s/;

var str = 'fee fi fo fum';

var myArray = str.match(re);

console.log(myArray);

g 플래그 없이 매칭

 

g 플래그를 사용할 때, String의 match 메소드와, RegExp의 exce 메소드의 사용 방법은 다릅니다. exec 메소드를 사용할 경우, 아래와 같이 사용해야 모든 매칭된 문자열을 가져올 수 있습니다.

1

2

3

4

var re = /\w+\s/g;

var xArray;

while(xArray = re.exec(str))

    console.log(xArray);

exec에서 g 플래그

i 플래그를 이용하여 대소문자 구별없이 검색

1

2

3

4

var re = /Fee/gi;

var str = 'fee fi fo fum';

var myArray = str.match(re);

console.log(myArray);

i 플래그

 

m 플래그를 이용하여 다중행 시작/끝 문자 검색

1

2

3

4

var re = /^t/m;

var str = 'fee fi fo fum \ntest';

var myArray = str.match(re);

console.log(myArray);

m 플래그

 

y 플래그를 이용하여 검색 위치 조정

1

2

3

4

5

6

7

8

var str = '#foo#';

var regex = /foo/y;

 

regex.lastIndex = 1;

console.log(regex.exec(str)); // foo와 매칭됨

regex.lastIndex = 5;

console.log(regex.exec(str)); // 매칭되지 않음

console.log(regex.lastIndex); // 0 (매칭되지 않을 경우 0으로 초기화)

y 플래그



출처: https://beomy.tistory.com/21 [beomy]

반응형
LIST

+ Recent posts