제로베이스 네카라쿠배 온라인스쿨 1기 과정(2021. 11 ~ 2021. 12)에서 공부했던 Javascript Deepdive 교재의 내용 요약 및 필자의 생각을 정리한 내용입니다. 원서의 내용 챕터의 일부를 요약한 내용으로 보다 자세한 내용은 원서를 참조 바랍니다.
31장 RegExp
31.1 정규 표현식이란?
- 정규 표현식(Regular Expression)은 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어(formal language)다. 정규 표현식은 자바스크립트의 고유 문법이 아니며, 대부분의 프로그래밍 언어와 코드 에디터에 내장되어 있다.
- 자바스크립트는 펄의 정규 표현식 문법을 ES3부터 도입했다.
- 정규 표현식은 문자열을 대상으로 패턴 매칭 기능을 제공한다.
- 패턴 매칭 기능이란 특정 패턴과 일치하는 문자열을 검색하거나 추출 또는 치환할 수 있는 기능을 말한다.
// 사용자로부터 입력받은 휴대폰 전화번호
const tel = "010-1234-567팔"
// 정규 표현식 리터럴로 휴대폰 전화번호 패턴을 정의한다.
const regExp = /^\d{3}-\d{4}-\d{4}$/
// tel이 휴대폰 전화번호 패턴에 매칭하는지 테스트(확인) 한다.
regExp.test(tel)
- 정규표현식을 사용하지 않으면 한 문자씩 연속해서 체크해야 한다.
- 정규표현식을 사용하면 반복문과 조건문 없이 패턴을 정의하고 테스트하는 것으로 간단히 체크할 수 있다.
- 단, 주석이나 공백을 허용하지 않고 여러 가지 기호를 혼합하여 사용하므로 가독성이 좋지 않다.
31.2 정규 표현식의 생성
- 정규 표현식 객체(RexExp 객체)를 생성하기 위해서는 정규 표현식 리터럴과 RegExp 생성자 함수를 사용할 수 있다.
- 일반적인 방법은 정규 표현식 리터럴을 사용하는 것이다.
- ’/ /’ 시작 종료 기호
- 패턴
- 플래그
const target = "Is this all there is?"
// 패턴: is
// 플래그: i => 대소문자를 구별하지 않고 검색한다.
const regExp = /is/i
// test 메서드는 target 문자열에 대해 정규 표현식 regExp의 패턴을 검새가여 매칭 결과를 불리언으로 반환한다.
regExp.test(target)
const target = "Is this all there is?"
const regexp = new RegExp(/is/i) // ES6
// const regexp = new RegExp(/is/, 'i');
// const regexp = new RegExp('is', 'i');
regexp.test(target)
31.3 RegExp 메서드
- 정규표현식 사용 메서드
- RegExp.prototype.exec
- RegExp.prototype.test
- String.prototype.match
- String.prototype.replace
- String.prototype.search
- String.prototype.split
31.3.1 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 플래그를 지정해도 첫 번째 매칭 결과만 반환한다.
31.3.2 RegExp.prototype.test
- test 메서드는 인수로 전달받은 문자열에 대해 정규 표현식의 패턴을 검색하여 매칭 결과를 불리언 값으로 반환한다.
const target = "Is this all there is?"
const regExp = /is/
regExp.test(target) // true
31.3.3 String.prototype.match
- String 표준 빌트인 객체가 제공하는 match 메서드는 대상 문자열과 인수로 전달받은 정규 표현식과의 매칭 결과를 배열로 반환한다.
const target = "Is this all there is?"
const regExp = /is/
regExp.match(target)
// -> ['is', index: 5, input: 'Is this all there is?", groups: undefined]
- String.prototype.match 메서드는 g 플래그가 지정되면 모든 매칭 결과를 배열로 반환한다.
31.4 플래그
- 패턴과 함께 정규 표현식을 구성하는 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
- 플래그는 총 6개가 있고 그 중 중요한 3개는 다음과 같다.
플래그 | 의미 | 설명 |
---|---|---|
i | Ignore case | 대소문자를 구별하지 않고 패턴을 검색한다. |
g | Global | 대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다. |
m | Multi line | 문자열의 행이 바뀌더라도 패턴 검색을 계속한다. |
- 플래그는 옵션이므로 선택적으로 사용할 수 있으며, 순서와 상관없이 하나 이상의 플래그를 동시에 설정할 수도 있다.
- 어떠한 플래그를 사용하지 않은 경우 대소문자를 구별해서 패턴을 검색한다.
- 문자열에 패턴 검색 매칭 대상이 1개 이상 존재해도 첫 번째 매칭한 대상만 검색하고 종료한다.
const target = "Is this all there is?"
// target 문자열에서 is 문자열을 대소문자를 구별하여 한 번만 검색한다.
target.match(/is/)
// target 문자열에서 is 문자열을 대소문자를 구별하지 않고 한 번만 검색한다.
target.match(/is/i)
// target 문자열에서 is 문자열을 대소문자를 구별하여 전역 검색한다.
target.match(/is/g)
// target 문자열에서 is 문자열을 대소문자를 구별하지 않고 전역 검색한다.
target.match(/is/gi)
31.5 패턴
- 정규 표현식은 “일정한 규칙을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어”다.
- 정규 표현식은 패턴과 플래그로 구성된다.
- 정규 표현식 패턴은 문자열의 일정한 규칙을 표현하기 위해 사용하며, 정규 표현식 플래그는 정규 표현식의 검색 방식을 설정하기 위해 사용한다.
- 패턴은 /로 열고 닫으며 문자열의 따옴표는 생략한다.
- 따옴표를 포함하면 따옴표까지도 패턴에 포함되어 검색된다.
- 패턴은 특별한 의미를 가지는 메타문자 또는 기호로 표현할 수 있다.
- 어떤 문자열 내에 패턴과 일치하는 문자열이 존재할 때 ‘정규표현식과 매치’한다고 표현한다.
31.5.1 문자열 검색
- 정규 표현식의 패턴에 문자 또는 문자열을 지정하면 검색 대상 문자열에서 패턴으로 지정한 문자 또는 문자열을 검색한다.
- 검색 대상 문자열과 플래그를 생략한 정규 표현식의 매칭 결과를 구하면 대소문자를 구별하여 정규 표현식과 매치한 첫 번째 결과만 반환한다.
- 대소문자를 구별하지 않고 검색하려면 플래그 i를 사용한다.
- 검색 대상 문자열 내에서 패턴과 매치하는 모든 문자열을 전역 검색하려면 플래그 g를 사용한다.
31.5.2 임의의 문자열 검색
- .은 임의의 문자 한 개를 의미한다.
- 문자의 내용은 무엇이든 상관없다.
const target = "Is this all there is?"
// 임의의 3자리 문자열을 대소문자를 구별하여 전역 검색한다.
const regExp = / ... /g
target.match(regExp)
31.5.3 반복 검색
- {m,n}은 앞선 패턴이 최소 m번, 최대 n번 반복되는 문자열을 의미한다. 콤마 뒤에 공백이 있으면 정상 동작하지 않으므로 주의해야 한다.
const target = "A AA B BB Aa Bb AAA"
// A가 최소 1번, 최대 2번 반복되는 문자열을 전역 검색한다.
const regExp = /A{1,2}/g
console.log(target.match(regExp))
-
{n}은 앞선 패턴이 n번 반복되는 문자열을 의미한다. 즉 {n}은 {n,n}과 같다.
-
{n,}은 앞선 패턴이 최소 n번 이상 반복되는 문자열을 의미한다.
-
+는 앞선 패턴이 최소 한번 이상 반복되는 문자열을 의미한다.
- 즉, +는 {1, }과 같다.
const target = "A AA B BB Aa Bb AAA"
// A가 최소 1번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /A+/g
target.match(regExp)
- ?는 앞선 패턴이 최대 한 번(0번 포함) 이상 반복되는 문자열을 의미한다.
- 즉, ?는 {0, 1}과 같다.
const target = "color colour"
// 'colo' 다음 'u'가 최대 한 번(0번 포함) 이상 반복되고 'r'이 이어지는
// 문자열 'color', 'colour'를 전역 검색한다.
const regExp = /colou?r/g
target.match(regExp)
31.5.4 OR 검색
- |은 or의 의미를 갖는다. 다음 예제의 /A|B/는 ‘A’ 또는 ‘B’를 의미한다.
const target = "A AA B BB Aa Bb AAA"
// 'A' 또는 'B'를 전역 검색한다.
const regExp = /A|B/g
target.match(regExp) // -> ["A", "AA", "B", "BB", "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) // -> ["A", "AA", "B", "BB", "A", "B"]
- 범위를 지정하려면 [] 내에 -를 사용한다.
const target = "A AA BB ZZ Aa Bb"
// 'A' ~ 'Z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
// 'A', 'AA', 'AAA', ... 또는 'B', 'BB', 'BBB', ... ~ 또는 'Z', 'ZZ', 'ZZZ', ...
const regExp = /[A-Z]+/g
target.match(regExp) // -> ["A", "AA", "BB", "ZZ", "A", "B"]
- 대소문자를 구별하지 않고 알파벳을 검색하는 방법은 다음과 같다.
const target = "AA BB Aa Bb 12"
// 'A' ~ 'Z' 또는 'a' ~ 'z'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[A-Za-z]+/g
target.match(regExp) // -> ["AA", "BB", "Aa", "Bb"]
- 숫자를 검색하는 방법은 다음과 같다.
const target = "AA BB 12,345"
// '0' ~ '9'가 한 번 이상 반복되는 문자열을 전역 검색한다.
const regExp = /[0-9]+/g
target.match(regExp) // -> ["AA", "BB", "Aa", "Bb"]
- \d는 숫자를 의미하며, \d는 [0-9]와 같다.
- \D는 \d와 반대로 동작하며, 숫자가 아닌 문자를 의미한다.
const target = "AA BB 12,345"
// '0' ~ '9' 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색한다.
let regExp = /[\d,]+/g
target.match(regExp) // -> ["12,345"]
// '0' ~ '9'가 아닌 문자 또는 ','가 한 번 이상 반복되는 문자열을 전역 검색한다.
regExp = /[\D,]+/g
target.match(regExp) // ["AA BB ", ","]
- \w는 알파벳, 숫자, 언더스코어를 의미한다.
- \w는 [A-Za-z0-9_]와 같다.
- \W는 \w와 반대로 동작한다. 즉, \W는 알파벳, 숫자, 언더스코어가 아닌 문자를 의미한다.
31.5.5 NOT 검색
- […] 내의 ^은 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"]
31.5.6 시작 위치로 검색
- […] 밖의 ^은 문자열의 시작을 의미한다.
const traget = "https://poiemaweb.com"
//https로 시작하는지 검색한다.
const regExp = /^https/
regExp.test(target) // true;
31.5.7 마지막 위치로 검색
- $는 문자열의 마지막을 의미한다.
const target = "https://poiemaweb.com"
// 'com'으로 끝나는지 검사한다.
const regExp = /com$/
regExp.test(target) // -> true
31.6 자주 사용하는 정규표현식
31.6.1 특정 단어로 시작하는지 검사
- 검색 대상 문자열이 ‘http://’ 또는 ‘https://‘로 시작하는지 검사한다.
- […] 바깥의 ^은 문자열의 시작을 의미하고, ?은 앞선 패턴이 최대 한번(0번 포함)이상 반복되는지를 의미한다.
const url = 'https://example.com';
// 'http://' 또는 'https://'로 시작하는지 검사한다.
/^https?:\/\/\.test(url); // true
/^(http|https):\/\//.test(url);
31.6.2 특정 단어로 끝나는지 검사
- html로 끝나는지 검사 ($는 문자열의 마지막을 의미한다.)
const fileName = "index.html"
;/html$/.test(fileName) // true
31.6.3 숫자로만 이루어진 문자열인지 검사
const target = "12345"
;/^\d+$/.test(target)
31.6.4 하나 이상의 공백으로 시작하는지 검사
- \s는 여러 가지 공백 문자(스페이스, 탭 등)를 의미한다.
- 즉, \s는 [\t\r\n\v\f]와 같은 의미다.
const target = " Hi! "
// 하나 이상의 공백으로 시작하는지 검사한다.
;/^[\s]+/.test(target)
31.6.5 아이디로 사용 가능한지 검사
- 검색 대상 문자열이 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10자리인지 검사한다.
const id = "abc123"
// 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10자리인지 검사한다.
;/^[A-Za-z0-9]{4,10}$/.test(id)
31.6.6 메일 주소 형식에 맞는지 검사
const email = 'ungmo2@gmail.com'
/^[0-9a-zA-z]([-_\.]?[0-9a-zA-z])*@[0-9a-zA-z]([-_\.]?[0-9a-zA-Z]*\.[a-zA-z]{2,3}$/.test(email);
31.6.7 핸드폰 번호 형식에 맞는지 검사
const cellphone = "010-1234-5678"
;/^\d{3}-\d{3,4}-\d{4}$/.test(cellphone)
31.6.8 특수 문자 포함 여부 검사
- 특수 문자는 A-Za-z0-9 이외의 문자다.
const target = "abc#123"
;/[^A-Za-z0-9]/gi.test(target)
-
특수문자를 선택적으로 검사할 수 있는 방식 (p591)
-
특수 문자 제거할 때는 String.prototype.repalce 메서드 사용
target.replace(/[^A-Za-z0-9]/gi, "") // abc123