1) 정규 표현식이란?
정규 표현식은 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어다. 자바스크립트는 펄(Perl)의 정규 표현식 문법을 ES3부터 도입했다.
정규 표현식은 문자열을 대상으로 패턴 매칭 기능을 제공한다. 패턴 매칭 기능이란 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능을 말한다.
2) 정규 표현식의 생성
정규 표현식 객체를 생성하기 위해서는 정규 표현식 리터럴과 RegExp 생성자 함수를 사용할 수 있다.
정규 표현식 리터럴은 패턴과 플래그로 구성된다.
const target = 'Is this all there is?';
const regexp = /is/i;
regexp.test(target); // -> true
RegExp 생성자 함수를 사용하여 RegExp 객체를 생성할 수도 있다.
// new RegExp(pattern[, flag])
const regexp = new RegExp(/is/i); // ES6
3) RegExp 메서드
RegExp.prototype.exec
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 플래그를 지정해도 첫 번째 매칭 결과만 반환한다.
RegExp.prototype.test
test 메서드는 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검색하여 매칭 결과를 불리언 값으로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/;
regExp.test(target); // -> true
String.prototype.match
String 표준 빌트인 객체가 제공하는 match 메서드는 대상 문자열과 인수로 전달받은 정규 표현식과의 매칭 결과를 배열로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/;
target.match(regExp);
// -> ['is', index: 5, input: 'Is this all there is?', groups: undefined]
match 메서드는 g 플래그가 지정되면 모든 매칭 결과를 배열로 반환한다.
const target = 'Is this all there is?';
const regExp = /is/g;
target.match(regExp); // -> ['is', 'is']
4) 플래그
플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
플래그는 총 6개 있다.
플래그 | 의미 | 설명 |
i | Ignore case | 대소문자를 구별하지 않고 패턴을 검색한다. |
g | Global | 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다. |
m | Multi line | 문자열의 행이 바뀌더라도 패턴 검색을 계속한다. |
플래그는 옵션이므로 선택적으로 사용할 수 있으며, 순서와 상관없이 하나 이상의 플래그를 동시에 설정할 수도 있다.
어떠한 플래그도 사용하지 않은 경우 대소문자를 구별해서 패턴을 검색한다. 그리고 문자열에 패턴 검색 매칭 대상이 1개 이상 존재해도 첫 번째 매칭한 대상만 검색하고 종료한다.
const target = 'Is this all there is?';
target.match(/is/);
// -> ['is', index: 5, input: 'Is this all there is?', groups: undefined]
target.match(/is/i);
// -> ['Is', index: 0, input: 'Is this all there is?', groups: undefined]
target.match(/is/g);
// -> ['is', 'is']
target.match(/is/ig);
// -> ['Is', 'is', 'is']
5) 패턴
패턴은 문자열의 일정한 규칙을 표현하기 위해 사용한다.
패턴은 /로 열고 닫으며 문자열의 따옴표는 생략한다. 따옴표를 포함하면 따옴표까지도 패턴에 포함되어 검색된다.
문자열 검색
정규 표현식의 패턴에 문자 또는 문자열을 지정하면 검색 대상 문자열에서 패턴으로 지정한 문자 또는 문자열을 검색한다.
- 검색 대상 문자열과 플래그를 생략한 정규 표현식의 매칭 결과를 구하면 대소문자를 구별하여 정규 표현식과 매치한 첫 번째 결과만 반환한다.
- 대소문자를 구별하지 않고 검색하려면 플래그 i를 사용한다.
- 검색 대상 문자열 내에서 패턴과 매치하는 모든 문자열을 전역 검색하려면 플래그 g를 사용한다.
임의의 문자열 검색
.은 임의의 문자 한 개를 의미한다. 문자의 내용은 무엇이든 상관없다.
const target = 'Is this all there is?';
// 임의의 3자리 문자열을 대소문자를 구별하여 전역 검색한다.
const regExp = /.../g;
target.match(regExp);
// -> ['Is ', 'thi', 's a', 'll ', 'the', 're ', 'is?']
반복 검색
{m,n}은 앞선 패턴이 최소 m번, 최대 n번 반복되는 문자열을 의미한다. 콤마 뒤에 공백이 있으면 정상 동작하지 않는다.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 최소 1번, 최대 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A{1,2}/g;
target.match(regExp); // -> ['A', 'AA', 'A', 'AA', 'A']
{n}은 앞선 패턴이 n번 반복되는 문자열을 의미한다.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A{2}/g;
target.match(regExp); // -> ['AA', 'AA']
{n,}은 앞선 패턴이 최소 n번 이상 반복되는 문자열을 의미한다.
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 최소 2번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /A{2,}/g;
target.match(regExp); // -> ['AA', 'AAA']
+는 앞선 패턴이 최소 한 번 이상 반복되는 문자열을 의미한다. = {1,}
const target = 'A AA B BB Aa Bb AAA';
// 'A'가 최소 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /A+/g;
target.match(regExp); // -> ['A', 'AA', 'A', 'AAA']
?는 앞선 패턴이 최대 한 번(0번 포함) 이상 반복되는 문자열을 의미한다. ={0,1}
const target = 'color colour';
// 'colo' 다음 'u'가 최대 한 번 이상 반복되고 'r'이 이어지는 문자열 검색
const regExp = /colou?r/g;
target.match(regExp); // -> ['color', 'colour']
OR 검색
|는 or의 의미를 갖는다.
const target = 'A AA B BB Aa Bb';
// 'A' 또는 'B'를 전역 검색한다.
const regExp = /A|B/g;
target.match(regExp);
// -> ['A', 'A', 'A', 'B', 'B', 'B', 'A', 'B']
분해되지 않은 단어 레벨로 검색하기 위해서는 +를 함께 사용한다.
const regExp = /A+|B+/g;
target.match(regExp); // -> ['A', 'AA', 'B', 'BB', 'A', 'B']
[ ] 내의 문자는 or로 동작한다.
const regExp = /[AB]+/g;
target.match(regExp); // -> ['A', 'AA', 'B', 'BB', 'A', 'B']
범위를 지정하려면 [ ] 내에 -를 사용한다.
const target = 'A AA BB ZZ Aa Bb';
// 'A' ~ 'Z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[A-Z]+/g;
target.match(regExp); // -> ['A', 'AA', 'BB', 'ZZ', 'A', 'B']
- 대문자 알파벳 검색 ⇒ /[A-Z]/
- 대소문자를 구별하지 않고 알파벳 검색 ⇒ /[A-Za-z]/
- 숫자 검색 ⇒ /[0-9]/
\d는 숫자를 의미한다. ↔ \D는 숫자가 아닌 문자를 의미한다.
const target = 'AA BB 12,345';
let regExp = /[\\d,]+/g;
target.match(regExp); // -> ['12,345']
regExp = /[\\D,]+/g;
target.match(regExp); // -> ['AA BB ', ',']
\w는 알파벳, 숫자, 언더스코어를 의미한다. ↔ \W는 알파벳, 숫자, 언더스코어가 아닌 문자를 의미한다.
const target = 'AA BB 12,345 _$%&';
let regExp = /[\\w,]+/g;
target.match(regExp); // -> ['AA', 'BB', '12,345', '_']
let regExp = /[\\W,]+/g;
target.match(regExp); // -> [' ', ' ', ',', ' ', '$%&']
NOT 검색
[…] 내의 ^은 not의 의미를 갖는다.
const target = 'AA BB 12 Aa Bb';
// 숫자를 제외한 문자열을 전역 검색한다.
const regExp = /[^0-9]+/g;
target.match(regExp); // -> ['AA BB ', ' Aa Bb']
시작 위치로 검색
[…] 밖의 ^은 문자열의 시작을 의미한다.
const target = '<https://naver.com>';
// 'https'로 시작하는지 검사한다.
const regExp = /^https/;
regExp.test(target); // -> true
마지막 위치로 검색
$는 문자열의 마지막을 의미한다.
const target = '<https://naver.com>';
// 'com'으로 끝나는지 검사한다.
const regExp = /com$/;
regExp.test(target); // -> true
😎 문자열의 시작과 끝을 표시하는 메타 문자는 옵션에 따라 줄 단위나 문서 전체를 의미할 수 있다.
◾ ^: 문자열의 시작
◾ $: 문자열의 종료
※ 메타 문자: 다른 언어에서 연산자나 예약어로 쓰이는 문자
6) 자주 사용하는 정규표현식
특정 단어로 시작하는지 검사
검색 대상 문자열이 ‘http://’ 또는 ‘https://’로 시작하는지 검사 ⇒ ^ ?
const url = '<https://naver.com>';
/^https?:\/\//.test(url); // -> true
- ^는 문자열의 시작을 의미
- ?는 바로 앞의 패턴이 최대 한 번 이상 반복 → 0번 또는 1번 (있거나 없거나)
특정 단어로 끝나는지 검사
검색 대상 문자열이 ‘html’로 끝나는지 검사 ⇒ $
const fileName = 'index.html';
/html$/.test(fileName); // -> true
- $는 문자열의 종료를 의미
숫자로만 이루어진 문자열인지 검사
= 처음과 끝이 숫자이고 최소 한 번 이상 반복되는 문자열과 매치
const target = '12345';
/^\d+$/.test(target); // -> true
- ^는 문자열의 시작을 의미
- \d 는 숫자
- +는 앞선 패턴이 최소 한 번 이상 반복
- $는 문자열의 종료를 의미
하나 이상의 공백으로 시작하는지 검사
\s는 여러 가지 공백 문자(스페이스, 탭 등)을 의미한다. 즉 \s는 [\t\r\n\v\f]와 같은 의미다.
const target = ' Hi!';
/^[\s]+/.test(target); // -> true
- ^는 문자열의 시작을 의미
- \s는 공백 문자
- [] 내의 문자는 or로 동작한다
- [\s] 는 공백 문자 중 어떤 것이든
- +는 앞선 패턴이 최소 한 번 이상 반복
아이디로 사용 가능한지 검사
검색 대상 문자열이 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10가지인지 검사
const id = 'abc123';
/^[A-Za-z0-9]{4,10}$/.test(id); // -> true
- [] 내부에 -를 사용하면 범위를 의미한다
- A ~ Z, a ~ z, 0 ~ 9 (대소문자를 구별하지 않는 알파벳과 숫자 검색)
- {m,n}은 앞선 패턴이 최소 m번, 최대 n번 반복 → {4,10} = 4 ~ 10자리 문자열
- ^와 $를 같이 쓰면 정해진 패턴이 문자열 전체에 적용된다는 것을 의미
메일 주소 형식에 맞는지 검사
const regExp = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
const email1 = 'chyh0218@naver.com';
regExp.test(email1); // -> true
const email2 = '-chyh0@naver.com'; // -> false
const email3 = 'chyh-0218@naver.com'; // -> true
const email4 = 'chyh0218@n.com'; // -> true
const email5 = 'chyh0218@naver.c'; // -> false
- ^는 문자열의 시작을 의미
- [] 내부의 문자는 or로 동작 → 숫자 또는 대소문자를 구별하지 않는 알파벳으로 시작
- ?는 앞선 패턴이 최대 한 번 반복 → -_\. 이 한 번 나오거나 안 나오거나
- *는 앞선 패턴이 일치하지 않거나 한 번 이상 반복 = {0,}
- \.은 특수문자 .를 의미
- {m,n}은 최소m번, 최대n번의 패턴 반복을 의미
- $는 문자열의 종료를 의미
핸드폰 번호 형식에 맞는지 검사
const cellphone = '010-1234-5678';
/^\d{3}-\d{3,4}-\d{4}$/.test(cellphone);
- \d는 숫자
- {n}은 패턴 n 번 반복
- {m,n}은 패턴 최소m번 ~ 최대n번 반복
특수 문자 포함 여부 검사
특수 문자는 A-Za-z0-9 이외의 문자다.
const target = 'abc#123';
(/[^A-Za-z0-9]/gi).test(target); // -> true
- ^를 [] 내부에 쓰면 NOT의 의미를 가진다. 즉 뒤의 패턴을 제외한 나머지 문자를 의미한다.
선택적으로 검사할 수도 있다.
(/[\{\}\[\]\/?.,;:|\)*~`!]/gi).test(target); // -> false
특수 문자를 제거할 때는 String.prototype.replace 메서드를 사용한다.
target.replace(/[^A-Za-z0-9]/gi, ''); // -> 'abc123'
?:
날짜에 대한 정규표현식 검사를 실행할 때 사용된 걸 보고 궁금해서 찾아봤다.
?:는 비캡처링 그룹을 지정하는데 사용된다.
즉, ?:를 사용하면 정규표현식의 일부를 그룹화하지만 해당 그룹이 캡처되지 않게 할 수 있다.
그렇다면 '캡처된다'는 무엇일까?
(\d{4})-(\d{2})-(\d{2})
다음과 같은 날짜 형식을 나타내는 정규표현식이 있을 때, 이 표현식을 문자열 '2024-04-12'에 적용하게 되면 ()를 기준으로 그룹화된 결과가 나오게 된다.
- 첫 번째 그룹 (\d{4}): "2024"
- 두 번째 그룹 (\d{2}): "04"
- 세 번째 그룹 (\d{2}): "12"
즉, 캡처란 정규표현식에서 추출하고자 하는 텍스트의 일부분을 식별하고 추출하는 것이다.
이때 만약 비캡처링 그룹을 사용하면 해당 그룹이 캡처되지 않고 그룹화만 수행되며, 추출되지 않는다.
출처: 이웅모, 『모던 자바스크립트 Deep Dive』 - 위키북스
'Javascript > 모던 자바스크립트' 카테고리의 다른 글
[ 모던 자바스크립트 ] 33. 7번째 데이터 타입 Symbol (+enum) (0) | 2024.04.16 |
---|---|
[ 모던 자바스크립트 ] 32. String (0) | 2024.04.15 |
[ 모던 자바스크립트 ] 30. Date (0) | 2024.04.11 |
[ 모던 자바스크립트 ] 29. Math (0) | 2024.04.11 |
[ 모던 자바스크립트 ] 28. Number (0) | 2024.04.09 |