javascript - 정규식 (Regular Expression)

 

은근히 정규식을 사용할 일이 많아 정규식에서 사용되는 특수문자들의 기능, 자주 사용하는 정규식에 대해 정리해보고자 이 포스팅을 작성하게 되었다.

출처는 모두 아래 페이지에 있다.

 

Mozilla : https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/정규식#special-negated-look-ahead

 

정규 표현식

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,��

developer.mozilla.org

 


 

정규식 사용법
// 리터럴
const reg = /ab*c/;

// 생성자 함수 이용
let Reg = new RegExp("ab*c");

표현식이 변할 수 있는 경우 생성자 함수를,

그렇지 않은 경우 리터럴을 사용하는 것이 권장된다.

 


 

정규식 - 특수 문자

 

문자 설명
\(백슬래시) 특수 문자에 사용: 문자 그대로 인식하기 위해 사용.
ex) \*, \\

일반 문자에 사용: 어떤 단어도 아닌 것이 되어버림. "단어 경계 문자"로 사용
ex) "moon"은 /oo\b/에 대응되지 않는데, n이 문자이기 때문. /oon\b/에는 대응된다.
^ 일반: start symbol이 해당 문자인지 확인
패턴에 쓰이면: 해당 패턴 내 없는 문자인지(역 문자셋) 확인
$ end symbol이 해당 문자인지 확인
* 0회 이상
+ 1회 이상
? 0회 또는 1회 "만", 최대한 많은 문자에 대응되는 *, +와 달리 ?는 오직 하나의 문자에만 대응
(이 점을 이용해 *, +, {} 등의 탐욕성을 제어할 수도 있음)
사전 검증에도 사용된다.
ex) /e?le?/ 은 l, el, le, ele 에 모두 대응된다.
. \n(개행 문자)를 제외한 모든 단일 문자와 대응.
(x) 대응된 값을 기억. 기억된 문자열은 이후 다른 곳에서 사용하기 위하여 불러와질 수 있음.
(?:x) 대응된 값을 기억하지 않는, 비포획 괄호. 실제 괄호 의미로 쓰고 싶을 때 사용.
ex) /(?:abc)+/ 하면 abc가 1번 이상 반복 시 매칭. 이걸 (abc)+로 쓰면 원래의 의도 손상.
x(?=y) y가 뒤따라오는 x에만 대응("lookahead"). y는 여러개일 수 있음.
ex) /apple(?=pie|juice)/ 를 테스트해보면 apple은 false, applepie와 applejuice는 true
x(?!y) y가 뒤따라오지 않는 x에만 대응("negated lookahead").
ex) /\d+(?!\.)/ 는 .(dot)이 뒤따라오지 않는 숫자에만 대응 (소수의 소수부)
| or
{n} 앞에 위치한 문자가 n번 반복되는 경우에만 대응.
ex) a{2} 는 aa에만 대응
{n, m} (n <= m) 앞 문자가 n번 이상 m번 이하로 나타나는 경우에만 대응.
m번 까지만 대응됨에 주의
[] 패턴 타입을 지정.
패턴 타입: 한 문자의 범위를 해당 패턴으로 지정해주는 것. 이 안에서는 -(하이픈)을 제외한 특수 문자는 모두 일반 문자로 인식.
ex) /[a-d]/는 "brisket"의 'b'와 대응
ex) ^은 위에서 말했듯 not 패턴. /[^abc]/는 a,b,c를 제외한 문자 하나와 대응
\d 숫자에 대응. [0-9]와 동일.
\D 숫자 이외의 문자에 대응. [^0-9]와 동일.
\w 대소문자나 숫자와 대응(일반적인 "단어(word)"). [A-Za-z0–9_]와 동일.

 

이외의 문자열은 Mozilla 본문을 참조하자.

 


 

정규식 - 함수

 

이번에는 정규식이 어떤 함수와 함께 어떻게 사용되는지에 대해 정리해보자.

정규식 함수는 {정규식}.{함수("탐색할 문장")}의 형태를 띄며,

정규식과 주로 함께 사용되는 String 함수는 {문자열}.{함수(정규식)}의 형태를 띈다.

 

함수 설명
reg.exec("탐색할 문장") 해당 정규식과 대응되는 부분이 있다면
[ 대응되는 부분, 이 부분의 시작 인덱스, 입력된(탐색할) 문장, groups ]의 배열 객체 반환.
기억될 문자열(괄호에 들어간)이 있는 경우
[ 대응되는 부분, 기억될 부분, 대응 부분 시작 인덱스, 입력된 문장 ]의 배열 반환.
reg.test("탐색할 문장") 해당 정규식과 대응되는 부분이 있다면 true, 없다면 false를 반환
str.match(정규식) 다음 배열을 반환.
[ 해당 정규식과 대응되는 부분, 기억할 부분, 기억할 부분, ... ]
str.search(정규식) 대응되는 부분의 시작 index를 반환. 없으면 -1 반환.
str.replace(정규식, 바꿀 문자열) 정규식과 대응되는 부분을 바꿀 문자열로 대체.
str.split(정규식) 해당 정규식을 기준으로 문자열을 분리

 

함수가 이해가 안 되면 다음 예제들을 참고하자.

 

  • exec 예제
// exec의 index 정보 사용법
const reg = /(abc)/g;
let arr = reg.exec("this is abc.");
console.log(arr);
// 대응된 부분의 시작 index
console.log(arr.index);
// 입력된 문자열
console.log(arr.input);
// lastindex: 대응 부분 이후의 index (flag g가 있어야 사용 가능)
console.log(reg.lastIndex);

결과

[ 'abc', 'abc', index: 8, input: 'this is abc.', groups: undefined ]
8
this is abc.
11

 

  • match 예제
// match 메소드와 () 특수문자 사용법
const reg = /a(b)c(d)/;
const str = "abcde";
let arr = str.match(reg);
console.log(arr);
console.log(arr[1], arr[2]);

결과

[ 'abcd', 'b', 'd', index: 0, input: 'abcde', groups: undefined ]
b d

 

  • search 예제
// search
const reg = /apple/;
const str = "I like apple";
console.log(str.search(reg));

결과

7

 

  • replace 예제
// replace
const reg = /F/;
const str = "my grade is F.";
console.log(str.replace(reg, 'A+'));

결과

my grade is A+.

 

  • split 예제
// split
const reg = /a/;
const str = "bacadae";
console.log(str.split(reg));

결과

[ 'b', 'c', 'd', 'e' ]

 


 

정규식 - 플래그

 

정규 표현식 뒤에 플래그를 추가함으로써 다양한 검색 조건을 부여할 수 있다.

플래그의 종류는 다음과 같다.

 

플래그 설명
g 전역 검색
i 대소문자 구분하지 않고 검색
m 다중행 검색
s .(dot: 모든 문자)에 개행 문자 \n도 포함시킴
u 유니코드; 패턴을 유니코드 코드 포인트의 나열로 취급
y sticky 검색을 수행.

 

사실 g 말고는 별로 써본 기억이 없다. 따라서, flag에 대한 예시로는 mozilla에서 소개하는 g flag의 예시를 일부 참고했다.

 

  • exec와 match에서의 사용
const reg = /(?:f|m)./;
const str = "f1, f2, m1, f3, m2, m3, m4, f4";
console.log(reg.exec(str));
console.log(str.match(reg));

이 코드의 결과는 다음과 같다. 첫 번째 대응되는 문자를 찾으면 검색을 중단함을 알 수 있다.

[ 'f1', index: 0, input: 'f1, f2, m1, f3, m2, m3, m4, f4', groups: undefined ]
[ 'f1', index: 0, input: 'f1, f2, m1, f3, m2, m3, m4, f4', groups: undefined ]

정규식에 g를 붙인다면 결과가 다음과 같이 달라진다.

[ 'f1', index: 0, input: 'f1, f2, m1, f3, m2, m3, m4, f4', groups: undefined ]
[ 'f1', 'f2', 'm1', 'f3', 'm2', 'm3', 'm4', 'f4' ]

exec의 결과는 동일하지만, match의 경우 매치되는 문자열을 모두 포함한 list를 반환함을 알 수 있다.

 

 


 

자주 사용되는 정규식

 

정규식이 빛을 발하는 몇몇 상황이 있다. 이번에는 이러한 상황에 대해서 정리해보도록 하자.

이 표는 앞으로 생각나거나 깨달을 때마다 추가해 나갈 것이다.

 

상황 정규식
한글 /[ㄱ-ㅎ|ㅏ-ㅣ|가-힣]/
ID /\w{min,max}/
전화번호 /\d{3}-\d{3,4}-\d{4}/