[기본 개념] 정규 표현식

728x90

[기본 개념] 정규 표현식

1> 정규 표현식 구성

2> 정규식 메서드

3> 정규식 플래그

4> 정규식 기호모음

5> 정규식 그룹화

6> 정규 표현식 테스트 사이트

 

정규 표현식 구성

 슬래쉬 문자 두 개 사이로 정규식 기호가 들어가는 형태이다.

 

2 정규식 메서드

메서드 설명
("문자열").match(/정규표현식/플래그) "문자열"에서 "정규표현식"에 매칭되는 항목들을 배열로 반환
("문자열").replace(/정규표현식/, "대체문자열") "정규표현식"에 매칭되는 항목을 "대체문자열"로 변환
("문자열").split(정규표현식) "문자열"을 "정규표현식"에 매칭되는 항목으로 쪼개어 배열로 반환
(정규표현식).test("문자열") "문자열"이 "정규표현식"과 매칭되면 true, 아니면 false 반환
(정규표현식).exec("문자열") match 메서드와 유사(단, 무조건 첫번째 매칭 결과만 반환)

3 정규식 플래그

 정규식 플래그는 정규식을 생성할 때 고급 검색을 위한 전역 옵션을 설정할 수 있도록 지원하는 기능이다.

 

플래그 의미 설명
i Insensitive  대소문자를 구별하지 않고 검색
g Global 문자열 내의 모든 패턴을 검색
m Multi Line 문자열의 행이 바뀌더라도 검색을 계속
s ​single line .​(모든 문자 정규식)이 개행 문자 \n도 포함하도록

`a1.a2\na3`.replace(/./g, 'z')
결과: "zzzzz\nzz"

`a1.a2\na3`.replace(/./gs, 'z')
결과: "zzzzzzzz"

u unicode 패턴을 유니코드 코드 포인트의 나열로 취급

`a1a2a3`.replace(/\p{N}/g, 'z')
결과: "a1a2a3"

`a1a2a3`.replace(/\p{N}/gu, 'z')
결과: "a
zazaz"

(\p{...} 유니코드 범주 사용)
y sticky 문자열의 현재 위치부터 검색 ‘sticky’ 모드를 활성화

const str = 'aaabb';
const regex = /a/y;

regex.test(str); //true < aaabb 찾음
regex.test(str); //false < 찍고 초기화
regex.test(str); //true < aaabb 찾음
regex.test(str); //true < aaabb 찾음
regex.test(str); //true < aaabb 찾음
regex.test(str); //false < aaabb 찍고 초기화

 

g 플래그 : 전역 검색

 

g 플래그가 없는 경우 : 최초 검색 결과 1번만 반환

g 플래그가 있는 경우 : 모든 결과 배열로 반환

 

// `a`가 두 개 포함된 문자열
const str = "abcabc";

// `g` 플래그 없이는 최초에 발견된 문자만 반환
str.match(/a/); // ["a", index: 0, input: "abcabc", groups: undefined]

// `g` 플래그가 있으면 모든 결과가 배열로 반환
str.match(/a/g); // (2) ["a", "a"]

 

m 플래그 : 줄 바뀜 검색

 

 여러 줄의 문자열에서 필터링해야 할 때 사용한다.

 

 입력 시작(^) 앵커입력 종료($) 앵커는 전체 문자열이 아닌 각 줄 별로 대응되게 만들어졌기 때문에 여러 줄을 검색해야 한다면 사용한다.

 

// 줄바꿈이 포함된 3줄 문자열
const str = "Hello World and\nPower Hello?\nPower Overwhelming!!";
/*
Hello World and
Power Hello?
Power Overwhelming!!
*/

// Hello 단어로 시작하는지 검사 (^ : 문장 시작점을 의미)
str.match(/^Hello/); // ["Hello"]
// → 첫번째 줄은 잘 찾음

// Power 단어로 시작하는지 검사 (^ : 문장 시작점을 의미)
str.match(/^Power/); // null

// 따라서 m 플래그를 통해 개행되는 다음 줄도 검색되게 설정
str.match(/^Power/m); // ['Power']

// 세번째 줄도 검색되게 하고싶으면 g 플래그와 혼합 사용
str.match(/^Power/gm); // ['Power', 'Power']

4 정규식 기호 모음

정규식 특정 문자 숫자 매칭 패턴

 

패턴 설명
a-zA-Z 영어 알파벳 (- 으로 범위 지정)
ㄱ-ㅎ가-힣 한글 문자 (- 으로 범위 지정)
0-9 숫자 (- 으로 범위 지정)
. 모든 문자열 (숫자, 한글, 영어, 특수기호, 공백 모두)
줄바꿈 X
\d 숫자
\D 숫자가 아닌 것
\w 밑줄 문자(_)를 포함한 영 숫자 문자에 대응
[A-Za-z0-9_] 와 동일
\W \w 가 아닌 것
\s space 공백
\S space 공백이 아닌 것
\특수기호 특수기호 \* \^ \& \! \? ...등
\b 63개 문자(영문 대소문자 52개 + 숫자 10개 + 밑줄 문자(_))가 아닌 나머지 문자에 일치하는 경계 (boundary)
\B 63개 문자에 일치하는 경계
\x 16진수 문자에 일치
/\x61/는 a에 일치
\0 8진수 문자에 일치
/\141/은 a에 일치
\u 유니코드 (Unicode) 문자에 일치
/\u0061/는 a에 일치
\c 제어 (Control) 문자에 일치
\f 폼 피드 (FF, U+000C) 문자에 일치
\n 줄 바꿈 (LF, U+000A) 문자에 일치
\r 캐리지 리턴 (CR, U+000D) 문자에 일치

 

정규식 검색 기준 패턴

 

기호 설명
| OR
a|b
[] 괄호안의 문자들 중 하나. or 처리 묶음 보면 된다.
/abc/ : "abc"를 포함하는
/[abc]/ : "a" 또는 "b" 또는 "c" 를 포함하는
[다-바] : 다 or 라 or 마 or 바
[^문자] 괄호안의 문자를 제외한 것
/[^abc]/ a b c 3개 문자를 제외, /[^a-c]/ 와 같은 의미
 "brisket"의 'r', "chop."의 'h'에 대응 (g 플래그가 아님)

(대괄호 안에서 쓰면 제외의 뜻, 대괄호 밖에서 쓰면 시작점 뜻)
^문자열 특정 문자열로 시작 (시작점)
/^www/
문자열$ 특정 문자열로 끝남 (종착점)
/com$/

 

정규식 개수 반복 패턴

 

기호 설명
? 0회나 1회이상 연속으로 반복
/e?le?/ => el, ele, le, l 에 대응

*, +, ?, {} 뒤에 사용하면, 가능한 많이 대응시킨 수량자를 가능한 가장 적은 문자들에 대응시킴
 
"123abc"
/\d+/ => 123
/\d+?/ => 1 (g 플래그있으면 1, 2, 3)
* 0회 이상 연속으로 반복, {0,} 와 같은 의미
/apple*/ => appl 에 대응
+ 1회 이상 연속으로 반복, {1,} 와 같은 의미
/apple+/ => apple, appleee 등 에 대응
*? 없거나, 있거나 and 없거나, 최대 한 개 : 없음
{0} 와 동일
+? 최소 한 개, 있거나 and 없거나, 최대 한 개 : 한 개
{1} 와 동일
{n} n 개
{Min,} 최소 Min 개 이상
{Min, Max} 최소 Min 개 이상, 최대 Max 개 이하
{3,5}? == {3} 와 동일

 

정규식 그룹 패턴

 

기호 설명
() 그룹화 및 캡쳐
(?: 패턴) 그룹화 (캡쳐 X)
(?=) 앞쪽 일치 (Lookahead)
/ab(?=c)/ => c 가 뒤따라오는 ab 에만 대응
(?!) 부정 앞쪽 일치 (Negative Lookahead)
/ab(?!c)/ => c 가 뒤따라오지 않는 ab 에만 대응

"3.141"
/\d+(?!\.)/ => 141 에 대응
(?<=) 뒤쪽 일치 (Lookbehind)
/(?<=ab)c/  => ab 가 앞에 있는 c 에만 대응
(?<!) 부정 뒤쪽 일치(Negative Lookbehind)
/(?<!ab)c/ => ab 가 앞에 없는 c 에만 대응

5 정규식 그룹화

'kokokoko'.match(/ko+/); 		// "ko"
'kooookoooo'.match(/ko+/);	 	// "koooo"

 

 표현식 "ko+" 은 "o" 만 + 를 적용시켜 ("k" 는 적용 X)

=> "koooo" 가 반환되었다. 

 

'kokokoko'.match(/(ko)+/); 		// "kokokoko", "ko"
'kooookoooo'.match(/(ko)+/); 		// "ko", "ko"

 

 하지만 표현식 "(ko)+" 는  "k" 와 "o" 를 묶었기 (그룹화) 때문에 "ko" 자체를 1회 이상 연속으로 반복

=> "kokokoko" 가 반환되었다.

 

 그런데 패턴 ( ) 를 사용한 정규식들의 결과는 2개가 나온다. 플래그 g 를 사용하지 않고, 한 번만 사용했는데 2개가 나온 이유는 캡처 기능 때문이다.

 

정규식 캡쳐 기능

 

 패턴 그룹화 ( ) 는 괄호 안의 표현식을 캡처하여 사용한다.

 

'kokokoko'.match(/(ko)+/); 		// "kokokoko", "ko"

 

1. 패턴 ( ) 안에 있는 "ko" 를 그룹화하여 캡처

2. 그룹화된 "ko" 를 패턴 + 로 1회 이상 반복되는 문자로 검색

("kokokoko" 반환)

3. 캡처 외 표현식이 모두 작동하고 난 뒤, 캡처된 표현식 "ko" 가 검색

("ko" 반환)

 

'123abc'.match(/(\d+)(\w)/); 		// "123a", "123", "a"

 

1. 패턴 ( ) 안에 있는 "\d+", "\w" 를 그룹화하여 캡처

2. 캡처 후 남는 표현식으로 검색

3. 그룹화된 "\d" 를 패턴 + 로 1회 이상 연속되는 숫자를 검색 "123" 일치

4. 다음 패턴 "\w" 는 문자를 검색하니 "a"가 일치 

("123a" 반환)

5. 첫 번째 캡처한 표현식 "\d+" 로 숫자를 재검색하되, 패턴 + 로 1회 이상 연속되는 숫자를 검색 "123" 일치

("123" 반환)

6. 나머지 캡쳐한 표현식 "\w" 로 문자를 재검색하니, "a" 일치

("a" 반환)

 

캡처하지 않는 그룹화 ?:

 

뜻하지 않은 정규식 그룹화 캡처 기능이 싫다면 괄호 안 ?: 문자를 통해 캡처를 비활성화 할 수 있다.

 

// 그룹화 + 캡처
'kokokoko'.match(/(ko)+/); 		// "kokokoko", "ko"

// 그룹화만
'kokokoko'.match(/(?:ko)+/); 		// "kokokoko"

 

 표현식 캡쳐를 하지 않기 때문에 "k" 와 "o" 를 그룹화 한 "ko" 만으로 검색되게 된다.

 

6 정규 표현식 테스트 사이트

 

https://regex101.com/

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

728x90