정규 표현식
은 "일정한 규칙(패턴)을 가진 문자열의 집합을 표현하기 위해 사용하는 형식언어"다. 해당 포스팅은 정규표현식의 메서드
와 정규표현식을 구성하는 패턴과 플래그
에 대해 살펴보겠다.
exec
메서드는 인수로 전달받은 문자열에 대해 정규표현식 패턴을 검색하여 매칭 결과를 배열로 반환한다. 매칭 결과가 없는 경우 null을 반환한다.
const target = 'Is this all there is?';
const regExp = /is/;
regExp.exec(target);
// ['is', index: 5, input: 'Is this all there is?', groups: undefined]
exec 메서드
는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과
만 반환한다.
test
메서드는 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검색하여 매칭 결과를 불리언 값
으로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/;
regExp.test(target); // true
String 표준 빌트인 객체가 제공하는 match
메서드는 대상 문자열
과 인수로 전달받은 정규표현식과의 매칭 결과를 배열
로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/g;
target.match(regExp); // ["is", "is"]
exec 메서드
는 문자열 내의 모든 패턴을 검색하는 g 플래그를 지정해도 첫 번째 매칭 결과
만을 반환한다.
반면 String.prototype.match
메서드는 g플래그가 지정되면 모든 매칭 결과
를 배열로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/g;
target.match(regExp); // [is, is]
regExp.exec(target); // ['is', index: 5, input: 'Is this all there is?', groups: undefined]
패턴과 함께 정규표현식을 구성하는 플래그
는 정규 표현식의 검색 방식을 설정
하기 위해 사용한다. 플래그는 총 6개가 있으며 그중 가장 중요한 3개의 플래그는 i, g, m
이 있다.
플래그 | 의미 | 설명 |
---|---|---|
i | Ignore case | 대소문자를 구별하지 않고 패턴을 검색한다. |
g | Global | 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다. |
m | Multi line | 문자열의 행이 바뀌더라도 패턴 검색을 계속한다. |
const target = 'Is this all there is?';
// 1. target 문자열에서 is문자열을 대소문자 구별하여 한 번만 검색한다.
target.match(/is/);
// ['is', index: 5, input: 'Is this all there is?', groups: undefined]
// 2. target 문자열에서 is문자열을 대소문자 구별하지 않고 한번만 검색한다.
target.match(/is/i);
// ['Is', index: 0, input: 'Is this all there is?', groups: undefined]
// 3. target 문자열에서 is 문자열을 대소문자 구별하여 전역 검색한다.
target.match(/is/g);
// (2) ['is', 'is']
// 4. target 문자열에서 is 문자열을 대소문자 구별하지 않고 전역 검색한다.
target.match(/is/ig);
// (3) ['Is', 'is', 'is']
정규 표현식은 "일정한 규칙(패턴)을 가진 문자열의 집합을 표현하기 위해 사용하는 형식언어"다. 정규표현식은 패턴과 플래그로 구성된다. 패턴
은 문자열의 일정한 규칙을 표현하기 위해 사용하며, 플래그
는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
정규 표현식의 패턴에 문자 또는 문자열을 지정
후 RegExp 메서드
를 사용하면 검색 대상 문자열에서 패턴으로 지정한 문자 또는 문자열을 검색할 수 있다.
const target = 'Is this all there is?';
// 'is' 문자열과 매치하는 패턴
// 플래그가 생략되었으므로 대소문자를 구별한다.
const regExp = /is/;
// target과 정규 표현식이 매치하는지 테스트한다.
regExp.test(target); // true
// target과 정규표현식의 매칭 결과를 구한다.
target.match(regExp); // ['is', index: 5, input: 'Is this all there is?', groups: undefined]
대소문자를 구별하지 않고 검색하려면 플래그 i를 사용한다.
const target = 'Is this all there is?';
// 'is' 문자열과 매치하는 패턴
// 플래그 i를 추가했으므로 대소문자를 구별하지 않는다.
const regExp = /is/i;
target.match(regExp);
// ['Is', index: 0, input: 'Is this all there is?', groups: undefined]0: "Is"groups: undefinedindex: 0input: "Is this all there is?"length: 1[[Prototype]]: Array(0)
검색 대상 문자열 내에서 패턴과 매치하는 모든 문자열을 전역 검색하려면 플래그 g를 사용한다.
const target = 'Is this all there is?';
const regExp = /is/ig;
target.match(regExp);
// (3) ['Is', 'is', 'is']
.
은 임의의 문자 한 개
를 의미한다. 문자 내용은 무엇이든 상관없다.
다음 예제의 경우 .을 3개 연속하여 패턴을 생성하였으므로 문자의 내용과 상관없이 3자리 문자열과 매치한다.
const target = 'Is this all there is?';
// 임의의 3자리 문자열을 대소문자 구별하여 전역 검색한다.
const regExp = /.../g;
target.match(regExp); // (7) ['Is ', 'thi', 's a', 'll ', 'the', 're ', 'is?']
{m,n}
은 앞서 패턴(다음 예제의 경우 A)이 최소 m번, 최대 n번 반복되는 문자열
을 의미한다. 콤마 뒤에 공백이 있으면 정상 동작하지 않으므로 주의하자.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A{1,2}/g;
target.match(regExp);
// (5) ['A', 'AA', 'A', 'AA', 'A']
{n,}
은 앞선 패턴(다음 예제의 경우 A)이 최대 n번 반복
되는 문자열을 의미한다.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A{2,}/g;
target.match(regExp);
// (2) ['AA', 'AAA']
+
는 앞선 패턴이 최소 한번 이상 반복되는 문자열을 의미한다. 즉 +는 {1,}
과 같다.
다음 예제는 앞선 패턴 'A'가 한 번 이상 반복되는 문자열, 즉 'A'로만 이루어진 문자열만 매치한다.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A+/g;
target.match(regExp); // (4) ['A', 'AA', 'A', 'AAA']
?
는 앞선 패턴이 최대 한번(0번 포함) 이상 반복
되는 문자열을 의미한다. 즉 ?는 {0,1}
과 같다.
다음 예제의 경우 /colou?r/는 'colo'다음 'u'가 최대 한 번 (0번 포함) 이상 반복되고 'r'이 이어지는 문자열 'color', 'colour'와 매치한다.
const target = 'color colour colouur';
// 'colo'다음 'u'가 최대 한 번 (0번 포함) 이상 반복되고 'r'이 이어지는 문자열을 전역검색
const regExp = /colou?r/g;
target.match(regExp); // (2) ['color', 'colour']
|
는 or의 의미를 갖는다.
다음 예제 /A|B/는 'A' 또는 'B'를 의미한다.
const target = 'A AA B BB Aa Bb';
const regExp1 = /A|B/g;
const regExp2 = /A|B/ig;
target.match(regExp1); // (8) ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B']
target.match(regExp2); // (10) ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'a', 'B', 'b']
분해되지 않은 단어
레벨로 검색하기 위해서는 +
를 함께 사용한다.
const target = 'A AA B Bb Aa Bb';
// 'A'또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA' ..., 'B', 'BB', 'BBB' ...
const regExp = /A+|B+/g;
target.match(regExp); // (6) ['A', 'AA', 'B', 'B', 'A', 'B']
위의 예제를 []
를 이용해 간단하게 표현할 수 있다. [] 내의 문자는 or로 동작
한다. 그 뒤에 +
를 이용하면 앞선 패턴을 한 번 이상 반복한다.
const target = 'A AA B Bb Aa Bb';
// 'A'또는 'B'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA' ..., 'B', 'BB', 'BBB' ...
const regExp = /[AB]+/g;
target.match(regExp); // (6) ['A', 'AA', 'B', 'B', 'A', 'B']
범위를 지정하려면 [] 내에 -를 사용
한다. 다음 예제의 경우 대문자 알파벳을 검색한다.
const target = 'A AA B Bb Aa Bb';
// 'A' ~ 'Z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA' ..., 'B', 'BB', 'BBB' ..., 'Z', 'ZZ' ...
const regExp = /[A-Z]+/g;
target.match(regExp); // (6) ['A', 'AA', 'B', 'B', 'A', 'B']
대소문자를 구별하지 않고 알파벳을 검색하는 방법은 다음과 같다.
const target = 'AA BB Aa Bb 12';
// 'A' ~ 'Z' 또는 'a' ~ 'z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[A-Za-z]+/g;
target.match(regExp); // (4) ['AA', 'BB', 'Aa', 'Bb']
숫자를 검색하는 방법은 다음과 같다.
const target = 'AA BB 12,345';
// '0' ~ '9'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[0-9]+/g;
target.match(regExp); // (2) ['12', '345']
위 예제의 경우 쉼표 때문에 매칭 결과가 분리되므로 쉼표를 패턴에 포함시켜보자.
const target = 'AA BB 12,345';
// '0' ~ '9' 또는 ',' 가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[0-9,]+/g;
target.match(regExp); // (1) ['12,345']
\d
는 숫자를 의미한다. 즉 \d
는 [0-9]와 같다. \D
는 \d와 반대로 숫자가 아닌 문자를 의미한다.
const target = 'AA BB 12,345';
// '0' ~ '9' 또는 ','가 한 번 이상 반복되는 문자열 전역검색
const regExp1 = /[\d,]+/g;
target.match(regExp1); // ['12,345']
// '0' ~ '9'가 아닌 문자(숫자가 아닌 문자) 또는 ','가 한 번 이상 반복되는 문자열 전역검색
const regExp2 = /[\D,]+/g;
target.match(regExp2); // (2) ['AA BB ', ',']
\w
는 알파벳, 숫자, 언더스코어를 의미한다. 즉 \w는 [A-Za-z0-9_]
이다.
\W
는 반대로 알파벳, 숫자, 언더스코어가 아닌 문자를 의미한다.
const target = 'Aa Bb 12,345 _$%&';
const regExp1 = /[\w,]+/g;
target.match(regExp1); // (4) ['Aa', 'Bb', '12,345', '_']
const regExp2 = /[\W,]+/g;
target.match(regExp2); // (5) [' ', ' ', ',', ' ', '$%&']
[...] 내의 ^
는 not
의 의미를 갖는다. 예를 들어 [^0-9]는 숫자를 제외한 문자를 의미한다.
따라서 \D는 [^0-9]
와 같고, \W는 [^A-Za-z0-9_]
와 같다.
const target = 'AA BB 12 Aa Bb';
// 숫자를 제외한
const regExp = /[^0-9]+/g;
target.match(regExp); // [AA, BB, Aa, Bb]
[...] 밖의 ^은 문자열의 시작
을 의미한다.
반면 [...] 내의 ^은 not
의 의미를 갖는다.
const target = 'https://poiemaweb.com';
// 'https'로 시작하는지 검사한다.
const regExp = /^https/;
regExp.test(target); // true
$
는 문자열의 마지막을 의미한다.
const target = 'https://poiemaweb.com';
// 'com'으로 끝나는지 검사한다.
const regExp = /com$/;
regExp.test(target); // true
문자열 중 두 개의 단어를 모두 포함
하는경우 조건을 만족하려면 (?=.*단어)(?=.*단어).*
를 하면 된다. 다음 예제는 https로 시작하고 com으로 끝나는지를 검사한다.
const target = 'https://poiemaweb.com';
const regExp = /(?=.*^https)(?=.*com$).*/;
regExp.test(target); // true
다음 예제는 검색 대상 문자열이 http://
또는 https://
로 시작하는지 검사한다.
[...] 바깥의 ^
은 문자열의 시작을 의미하고, ?
은 앞선 패턴(다음 예제의 경우 's')이 최대 한 번(0번 포함)이상 반복되는지를 의미한다. 다시 말해, 검색 대상 문자열에 앞선 패턴('s')이 있어도 없어도 매치된다.
const url = 'https://example.com';
const regExp = /^https?:\/\//;
regExp.test(url); // true
위의 패턴은 아래 패턴과 동일하다.
const regExp = /^(http|https):\/\//;
$
는 문자열의 마지막을 의미한다. 다음 예제는 검색 대상 문자열이 'http'로 끝나는지 검색한다.
const fileName = 'index.html';
const regExp = /html$/;
// 'html'으로 끝나는지 검사한다.
regExp.test(fileName); // true
[...] 바깥의 ^
은 문자열의 시작을, $
는 문자열의 마지막을 의미한다. \d
는 숫자를, +
는 앞선 패턴이 최소 한 번 이상 반복되는 문자열을 의미한다.
즉 검색 대상 문자열이 숫자로만 이루어진 문자열인지 검사한다.
const target = '12345';
// 숫자로만 이루어진 문자열인지 검사한다.
/^\d+$/.test(target); // true;
\s
는 여러 가지 공백 문자를 의미한다. 즉 \s
는 [\t\r\n\v\f]
와 같은 의미다.
다음 예제는 검색 대상 문자열이 하나 이상의 공백으로 시작하는지 검사한다.
const target = ' Hi! ';
const regExp = /^[\s]+/;
regExp.test(target)
다음 예제는 검색 대상 문자열이 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10자리인지 검사한다. {4,10}
은 앞선 패턴이 최소 4번, 최대 10번 반복되는 문자열인지를 의미한다.
const id = 'abc123';
const regExp = /^[A-Za-z0-9]{4,10}$/;
regExp.test(id); // true
다음 예제는 검색 대상 문자열이 메일 주소 형식에 맞는지 검사한다.
const email1 = 'fgStudy@gmail.com';
const email2 = 'fgStudy@gmail';
const regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*[a-zA-Z]{2,3}$/;
regExp.test(email1); // true
regExp.test(email2); // false
const phone = '010-1234-5678';
const regExp = /^\d{3}-\d{3,4}-\d{4}$/;
regExp.test(phone); // true
다음 예제는 검색 대상 문자열에 특수 문자가 포함되어 있는지를 검사한다. 특수문자는 A-Za-z0-9 이외의 문자이다.
const target = 'abc#123';
const regExp = /[^A-Za-z0-9]/gi;
regExp.test(target); // true
위의 예제는 다음과 같이 대체해서 사용할 수 있다. 이 방식은 특수 문자를 선택적으로 검사할 수 있다는 장점이 있다.
const regExp = /[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%&\\\=\(\'\"]/gi;
regExp.test(target); // true
replace()
메서드는 어떤 패턴에 일치하는 일부 또는 모든 부분이 교체된 새로운 문자열을 반환
한다. 패턴은 문자열이나 정규식(RegExp)이 될 수 있으며, 문자열 인 경우 첫 번째 문자열만 치환이 된다.
const target = 'abc#123';
const regExp = /[^A-Za-z0-9]/gi;
target.replace(regExp, ''); // abc123
docs:
1. 모던 자바스크립트 딥다이브 31장 RegExp
2. replace() 메서드 MDN