JAVA SCRIPT/Study

자바스크립트 정규 표현식

ㅈㅣㄴ 2023. 12. 5. 18:04
자바스크립트 정규 표현식

 


 

정규 표현식, 또는 정규식은 문자열에서 특정 문자 조합을 찾기 위한 패턴이다.

JavaScript 에서는 정규 표현식도 객체이다.

 


 

정규 표현식 만들기

 

두 가지 방법으로 만들 수 있다.

  • 정규 표현식 리터럴. 다음과 같이 슬래시로 패턴을 감싸서 작성한다.
const re = / ab + c / ;

 

정규 표현식 리터럴은 스크립트를 불러올 때 컴파일되므로, 바뀔 일이 없는 패턴의 경우 리터럴을 사용하면 성능이 향상될 수 있다.

 

 

  • RegExp 객체의 생성자 호출
const re = new RegExp("ab + c");

 

생성자 함수를 사용하면 정규 표현식이 런타임에 컴파일된다.

바뀔 수 있는 패턴이나, 사용자 입력 등 외부 출처에서 가져오는 패턴의 경우 이렇게 사용한다.

 

RegExp 객체는 리터럴 표기법과 생성자로써 생성할 수 있다.

리터럴 표기법의 매개변수는 두 빗금으로 감싸야 하며 따옴표를 사용하지 않는다.

생성자 함수의 매개변수는 빗금으로 감싸지 않으나 따옴표를 사용한다.

 

/ab+c/i;

new RegExp(/ab+c/, "i"); //리터럴
new RegExp("ab+c", "i"); //생성자

 

 

정규 표현식 패턴 작성하기

 

정규 표현식 패턴은 /abc/ 처럼 단순한 문자로 구성하거나, /ab+c/ 와 /Chapter (\d+)\.\d*/ 처럼 단순한 문자와 특수 문자의 조합으로 구성할 수도 있다.

특히 (\d+) 에 나타난 괄호는 정규 표현식에서 기억 장치처럼 쓰여서, 괄호의 안쪽 패턴과 일치한 부분을 나중에 사용할 수 있도록 기억한다.

 

단순 패턴 사용하기

 

단순 패턴은 문자열을 있는 그대로 탐색할 때 사용한다.

예를 들어, /abc/ 패턴은 문자열에서 정확한 순서로 "abc" 라는 문자의 조합이 나타나는 부분과 일치한다.

정확하게 "abc" 를 포함하는 문자열에서만 일치에 성공한다.

 

특수 문자 사용하기

 

하나 이상의 "b" 를 찾는다거나 공백 문자를 찾는 등 직접적인 일치 이상의 탐색이 필요할 땐 특수 문자를 사용한다.

예컨대 하나의 "a" 이후에 0개 이상의 "b", 그 뒤의 "c" 와 일치해야 하면 /ab*c/ 패턴을 사용할 수 있다.

"b" 뒤의 *는 "이전 항목의 0번 이상 반복" 을 의미한다.

이 패턴을 문자열 "cbbabbbbcdebc" 에 대해 사용하면, 일치하는 부분 문자열은 "abbbbc" 일 것이다.

 

정규 표현식 특수문자

 

어서션

: 줄이나 단어의 시작과 끝을 나타내는 경계와, 일치가 가능한 방법을 나타내는 패턴 (전방탐색, 후방탐색, 조건 표현식 등)이 포함된다.

 

문자 클래스

: 글자와 숫자처럼 다른 유형의 문자를 구분한다.

 

그룹과 범위

: 표현 문자의 그룹과 범위를 나타낸다.

 

수량자

: 일치할 문자나 표현이 반복되어야 할 횟수를 나타낸다.

 

유니코드 속성 이스케이프

: 대/소문자,  수학 기호, 문장 부호처럼, 유니코드 문자 속성에 따라 문자를 구분한다.

 

 

 

이스케이핑

 

특수 문자를 있는 그대로 탐색("*" 을 직접 찾는 등) 해야 하는 경우, 특수 문자 앞에 역슬래시(\) 를 배치해서 이스케이프 해야 한다. 예를 들어 "a" 뒤의 별표("*") 뒤의 "b" 와 일치해야 하면 /a\*b/ 를 사용하면 된다. 역슬래시가 "*" 를 "이스케이프" 해서, 특수 문자가 아닌 문자 리터럴로 취급한다.

 

마찬가지로, 슬래시(/)와 일치해야 하는 경우에도 이스케이프를 해야 한다.

그냥 빗금을 사용하면 패턴이 끝나버린다. 예를 들어 문자열 "/example/" 과 그 뒤 하나 이상의 알파벳을 찾으려면 /\/example\/[a-z]/ 를 사용할 수 있다. 각각의 슬래시 앞에 놓인 역슬래시가 슬래시를 이스케이프한다.

 

리터럴 역슬래시에 일치하려면 역슬래시를 이스케이프한다. "A:\", "B:\", "C:\", ..., "Z:\" 와 일치하는 패턴은 /[A-Z]:\\/ 이다.

앞의 역슬래시가 뒤의 역슬래시를 이스케이프해서, 결과적으로 하나의 리터럴 역슬래시와 일치하게 된다.

 

RegExp 생성자와 문자열 리터럴을 사용하는 경우, 역슬래시가 문자열 리터럴의 이스케이프로도 작동한다는 것을 기억해야 한다. 그러므로 정규 표현식의 역슬래시를 나타내려면 문자열 리터럴 수준의 이스케이프도 해줘야 한다. 즉, 앞서 살펴본 /a\*b/ 패턴을 생성하려면 new RegExp("a\\*b") 가 되어야 한다.

 

이스케이프되지 않은 문자열을 이미 가지고 있을 땐 String.replace를 활용해 이스케이프를 해줄 수도 있다.

function escapeRegExp(string) {
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&"); // $&은 일치한 문자열 전체를 의미
}

 

정규 표현식 뒤의 "g" 는 전체 문자열을 탐색해서 모든 일치를 반환하도록 지정하는 전역 탐색 플래그이다.

플래그에 대해서는 아래의 플래그를 활용한 고급 탐색에서 확인할 수 있다.

 

괄호 사용하기

 

정규 표현식의 아무 부분이나 괄호로 감싸게 되면, 그 부분과 일치하는 부분 문자열을 기억하게 된다.

기억한 부분 문자열은 불러와서 다시 사용할 수 있다.

 

정규 표현식 사용하기

 

정규 표현식은 RegExp 의 메서드 test() 와 exec()._(en-US), String 의 메서드 match(), replace()._(en-US), search()._(en-US), search()._(en-US), split() 에서 사용할 수 있다.

 

 

문자열 내부에 패턴과 일치하는 부분이 존재하는지만 알아내려면 test() 나 search() 메서드를 사용하면 된다.

더 느리더라도 일치에 관한 추가 정보가 필요하면 exec() 과 match() 메서드를 사용한다.

일치하는 부분이 존재하면, exec() 과 match() 는 일치에 관한 데이터를 포함한 배열을 반환하고, 일치에 사용한 정규 표현식 객체의 속성을 업데이트한다.

일치하지 못한 경우 null 을 반환한다. (null 은 조건 평가시 false 와 같다.)

 

정규 표현식을 문자열에서 만들고 싶으면 아래처럼 사용할 수도 있다.

const myRe = new RegExp("d(b+)d", "g");
const myArray = myRe.exec("cdbbdbsbz");

 

플래그를 활용한 고급 탐색

 

정규 표현식은 전역 탐색이나 대소문자 무시와 같은 특성을 지정하는 플래그를 가질 수 있다.

플래그는 단독으로도 사용할 수 있고, 순서에 상관없이 한꺼번에 여럿을 지정할 수도 있다.

 

 

 


 

사용법 정리

 

매칭 패턴

패턴
의미


a-zA-Z
영어알파벳(-으로 범위 지정)


ㄱ-ㅎ가-힣
한글 문자(-으로 범위 지정)


0-9
숫자(-으로 범위 지정)


.
모든 문자열(숫자, 한글, 영어, 특수기호, 공백 모두! 단, 줄바꿈X)


\d
숫자


\D
숫자가 아닌 것


\w
영어 알파벳, 숫자, 언더스코어(_)


\W
/w 가 아닌 것


\s
space 공백


\S
space 공백이 아닌 것


\특수기호
특수기호

 

검색 패턴

기호
의미


|
OR


[]
괄호안의 문자들 중 하나


[^문자]
괄호안의 문자를 제외한 것


^문자열
특정 문자열로 시작(괄호 없음 주의!)


문자열$
특정 문자열로 끝남


()
그룹 검색 및 분류(match메서드에서 그룹별로 묶어줌)


(?: 패턴)
그룹 검색(분류X)


\b
단어의 처음/끝


\B
단어의 처음/끝이 아님

 

갯수 패턴

기호
의미


?
최대 한번(없음 || 한개)


*
없거나 있거나 (없음 || 있음): 여러개 포함


+
최소 한개(한개 || 여러개)


{n}
n개


{Min,}
최소 Min개 이상


{Min, Max}
최소 Min개 이상, 최대 Max개 이하