모던 자바스크립트 Deep Dive : 31장 RegExp

EdLee·2022년 11월 20일

javascript

목록 보기
21/37

31장 RegExp

1. 정규표현식이란?


  • 일정한 패턴을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어
  • JS 고유 문법이 아니며, JS는 Perl의 정규 표현식 문법을 사용
  • 문자열을 대상으로 패턴 매칭 기능을 제공
// 사용자로부터 입력받은 휴대폰 전화번호
const tel = '010-1234-567팔';

// 정규 표현식 리터럴로 휴대폰 전화번호 패턴을 정의한다.
const regExp = /^\d{3}-\d{4}-\d{4}$/;

// tel이 휴대폰 전화번호 패턴에 매칭하는지 테스트(확인)한다.
regExp.test(tel); // -> false

2. 정규 표현식의 생성


2.1 정규 표현식 리터럴

const target = 'Is this all there is?';

// 패턴: is
// 플래그: i => 대소문자를 구별하지 않고 검색한다.
const regexp = /is/i;

// test 메서드는 target 문자열에 대해 정규표현식 regexp의 패턴을 검색하여 매칭 결과를 불리언 값으로 반환한다.
regexp.test(target); // -> true

2.2 RegExp 생성자 함수

/**
 * pattern: 정규 표현식의 패턴
 * flags: 정규 표현식의 플래스(g, i, m, u, y)
 */
new RegExp(pattern[, flags]);

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');

// test 메서드는 target 문자열에 대해 정규표현식 regexp의 패턴을 검색하여 매칭 결과를 불리언 값으로 반환한다.
regexp.test(target); // -> true
  • 변수를 사용해 동적으로 RegExp 객체 생성 가능
const count = (str, char) => (str.match(new RegExp(char, 'gi')) ?? []).length;
                         
count('Is this all there is?', 'is'); // 3
count('Is this all there is?', 'xx'); // 0

3. RegExp 메서드


3.1 regExp.prototype.exec

  • 인자로 전달받은 문자열에 대해 정규 표현식의 패턴 검색하여 첫번째 매칭 결과를 배열로 반환
const target = 'Is this all there is?';
const regExp = /is/;

target.match(regExp); // -> ["is", index: 5, input: "Is this all there is?", groups: undefined]

3.2 regExp.prototype.test

  • 인자로 전달받은 문자열에 대해 정규 표현식의 패턴 검색하여 매칭 결과를 boolean으로 반환
const target = 'Is this all there is?';
const regExp = /is/;

target.test(regExp); // true

3.2 regExp.prototype.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]
  • exec : g 플래그를 지정해도 첫 번째 매칭 결과만 반환
  • match : g 플래스 지정 시, 모든 매칭 결과를 배열로 반환
const target = 'Is this all there is?';
const regExp = /is/g;

target.match(regExp); // -> ["is", "is"]

4. 플래그


  • 정규 표현식의 검색 방식을 설정하기 위해 사용되는 6가지 플래그
  • 다음은 주로 사용되는 3개 플래그
플래그의미설명
iIgnore case대소문자를 구별하지 않고 패턴을 검색한다.
gGlobal대상 문자열 내에서 패턴과 일치하는 모든 문자열을 전역 검색한다.
mMulti line문자열의 행이 바뀌더라도 패턴 검색을 계속한다.
const target = 'Is this all there is?';

// target 문자열에서 is 문자열을 대소문자를 구별하여 한 번만 검색한다.
target.match(/is/);
// -> ["is", index: 5, input: "Is this all there is?", groups: undefined]

// target 문자열에서 is 문자열을 대소문자를 구별하지 않고 한 번만 검색한다.
target.match(/is/i);
// -> ["Is", index: 0, input: "Is this all there is?", groups: undefined]

// target 문자열에서 is 문자열을 대소문자를 구별하여 전역 검색한다.
target.match(/is/g);
// -> ["is", "is"]

// target 문자열에서 is 문자열을 대소문자를 구별하지 않고 전역 검색한다.
target.match(/is/ig);
// -> ["Is", "is", "is"]

5. 패턴


5.1 문자열 검색

const target = 'Is this all there is?';
const regExp = /is/ig;

// 플래그 i, 대소문자를 구별하지 않고 검색
// 플래그 g, 모든 문자열 전역 검색
target.match(regExp); // ["Is", "is", "is"]

5.2 임의의 문자열 검색

  • .은 임의의 문자열 한 개를 의미
const target = 'Is this all there is?';
const regExp = /.../g; // 임의의 문자열 3개를 의미

target.match(regExp); // ["Is ", "thi", "s a", "ll ", "the", "re ", "is?"]

5.3 반복 검색

  • {m,n} : 최소 m번, 최대 n번 반복되는 문자열을 의미
  • 위 패턴에 공백 넣으면 동작 안함
const target = 'A AA B BB Aa Bb AAA';
const regExp = /A{1,2}/g;

// A가 최소 1번 최대 2번 반복되는 문자열을 전역 검색
target.match(regExp); // ["A", "AA", "A", "AA", A"]

regExp = /A{2}/g; // 2번 반복
regExp = /A{2,}/g; // 최소 2번 이상
regExp = /A+/g; // 최소 1번 이상(={1,}}
  • ?는 패턴이 최대 한 번 이상 반복되는 문자열을 의미 (={0,1}}
const target = 'color colour';
const regExp = /colou?r/g;

// 'colo'다음 'u'가 최대 한 번(0번 포함)이상 반복되고 'r'이 이어지는 문자열을 전역 검색
target.match(regExp); // ["color", "colour"]

5.4 OR 검색

  • |는 or을 의미
const target = 'A AA B BB Aa Bb';
const regExp = /A|B/g;

// A또는 B를 전역 검색
target.match(regExp); // ["A", "A", "A", "B", "B", "B", "A", "B"]
  • [] 내의 문자는 or로 동작
  • -를 이용해 범위 지정 가능
const target = 'AA BB Aa Bb';
const regExp = /[A-Za-z]+/g;

// A~Z, a~z 가 1번 이상 반복되는 문자열을 전역 검색
target.match(regExp); // ["A", "BB", "Aa", "Bb"]

5.5 NOT 검색

  • [] 안의 ^는 not을 의미
const target = 'AA BB 12 Aa Bb';
const regExp = /[^0-9]+/g;

// A~Z, a~z 가 1번 이상 반복되는 문자열을 전역 검색
target.match(regExp); // ["AA BB ", " Aa Bb"]

5.6 시작 위치로 검색

  • [] 밖의 ^는 시작점을 나타냄
const target = 'https://www.google.com';
// https 로 시작?
const regExp = /^https/;

target.test(regExp); // true

5.7 마지막 위치로 검색

  • $는 문자열의 마지막을 의미
const target = 'https://www.google.com';
// com로 끝?
const regExp = /com$/;

target.test(regExp); // true

6. 자주 사용하는 정규표현식


6.1 특정 단어로 시작하는지 검사

const url = 'https://example.com';

// 'http://' 또는 'https://'로 시작하는지 검사한다.
/^https?:\/\//.test(url); // -> true

// 아니면,
/^(http|https):\/\//.test(url); // -> true

6.2 특정 단어로 끝나는지 검사

const fileName = 'index.html';

// 'html'로 끝나는지 검사한다.
/html$/.test(fileName); // -> true

6.3 숫자로만 이뤄진 문자열인지 검사

const target= '12345';

// [...]밖의 ^ : 숫자로 시작인지
// $ : 마지막이 숫자인지
// \d : 숫자
// + : 1회 이상 반복
/^\d+$/.test(target); // true

6.4 하나 이상의 공백으로 시작하는지 검사

const target= '  Hi!';

/^[\s]+/.test(target); // true

6.5 아이디로 사용 가능한지 검사

  • 알파벳 대소문자 또는 숫자로 시작하고 끝나야 한다.
  • 4~10자리인지 검사
const id = 'abc123';

// 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4 ~ 10자리인지 검사한다.
/^[A-Za-z0-9]{4,10}$/.test(id); // -> true

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); // -> true

6.7 핸드폰 번호 형식에 맞는지 검사

const cellphone = '010-1234-5678';

/^\d{3}-\d{3,4}-\d{4}$/.test(cellphone); // -> true

6.8 특수 문자 포함 여부 검사

const target = 'abc#123';

// A-Za-z0-9 이외의 문자가 있는지 검사한다.
(/[^A-Za-z0-9]/gi).test(target); // -> true

// 특수 문자를 선택적으로 검사하려면
(/[\{\}\[\]\/?.,;:|\)*~`!^\-_+<>@\#$%^\\\\=\(\'\"]/gi).test(target); // true

// 특수 문자 제거 시,
target.replace(/[^A-Za-z0-9]/gi, ''); // -> abc123

긁어온 거

// 1. 영문자 소문자, 숫자, "-", "_" 로만 구성된 길이 2 ~ 10자리 사이 문자열
/^[a-z0-9_-]{2,10}$/ 

// 2. 신용카드 번호
// 19자리 숫자와 "-"
/^[0-9-]{19}$/
// 4-4-4-4 체크:
/^[0-9]{4}[-\s\.]?[0-9]{4}[-\s\.]?[0-9]{4}[-\s\.]?[0-9]{4}$/

// 3. 영문자 대소문자와 숫자로만 구성
/[a-zA-Z0-9]/

//4. 전화번호
// 3자리-3~4자리-4자리(사이에 1자 아무거나 가능))
  /^[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3,4}[-\s\.]?[0-9]{4}$/

// 3자리-3~4자리-4자리(사이에 "-" 고정)
/^\d{3}-\d{3,4}-\d{4}$/

// 휴대폰&전화번호
/(^02.{0}|^01.{1}|[0-9]{3})([0-9]+)([0-9]{4})/

// 휴대폰번호
/^01(?:0|1|[6-9])[.-]?(\\d{3}|\\d{4})[.-]?(\\d{4})$/


// 5. UUID
/^[0-9a-fA-F]{8}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{4}\b-[0-9a-fA-F]{12}$/


// 6. 아스키II 코드만
/[ -~]/

// 7. 맥어드레스
/^[a-fA-F0-9]{2}(:[a-fA-F0-9]{2}){5}$/

// 8. IP주소(IPv4)
/(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}/

// 9. IP주소(IPv6)
/(([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|:((:[0-9a-fA-F]{1,4}){1,7}|:)|fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9])\.){3,3}(25[0-5]|(2[0-4]|1{0,1}[0-9]){0,1}[0-9]))/


// 10. 이메일주소
// 기본체크
/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/

// RFC5322
/\b[\w.!#$%&*+\/=?^`{|}~-]+@[\w-]+(?:\.[\w-]+)*\b/

// 정밀체크
/(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))/


// 11. 패스워드
// 최소 8자 이상으로 영문자 대문자, 영문자 소문자, 숫자, 특수문자가 각각 최소 1개 이상
/^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$ %^&*-]).{8,}$/

// 최소 8자 이상으로 숫자, 특수문자가 각각 최소 1개이상
/^(?=.*?[0-9])(?=.*?[#?!@$ %^&*-]).{8,}$/

// 12. URL
// 프로토콜 포함
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#()?&//=]*)/ 

// 프로토콜 옵션
/(https?:\/\/)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/ 


// 13. HTML 태그
/^<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)$/

/<\/?[\w\s]*>|<.+[\W]>/

/<([a-z]+)([^<]+)*(?:>(.*)<\/\1>|\s+\/>)/


// 14. 하이퍼링크
/(?!<a\sname=\"([\w\s\d\-\.\#]+)\"><\/a>)<a\sname=\"([\w\s\d\-\.\#]+)\">(.*?)<\/a>/

// 15. 숫자만인지 체크
^(\(?\+?[0-9]*\)?)?[0-9_\- \(\)]*$

// 16. 웹사이트 하이퍼링크인지 체크
<a\s+(?:[^>]*)href=\"((?:https:\/\/|http:\/\/)(?:.*?))">(?:.*?)<\/a>

// 17. 숫자와 영문자 대소문자만
// 공백없는 숫자와 영문자 대소문자
/^[a-zA-Z0-9]*$/

// 공백포함 숫자와 영문자 대소문자
/^[a-zA-Z0-9 ]*$/

// 영문자 대소문자
/[a-zA-Z]/

// 18. 년월일
yyyy-mm-dd: /^(19|20)\d\d([- /.])(0[1-9]|1[012])\2(0[1-9]|[12][0-9]|3[01])$/

// 19. 특수문자와 공백 선택
// 한글포함 특수문자와 공백
/[^?a-zA-Z0-9/]/

// 한글제외 특수문자와 공백
/[^--?a-zA-Z0-9/ ]/


// 20. 주민등록번호
/^[-A-Za-z0-9_]+[-A-Za-z0-9_.]*[@]{1}[-A-Za-z0-9_]+[-A-Za-z0-9_.]*[.]{1}[A-Za-z]{1,5}$/

0개의 댓글