인구의 20%가 이탈리아 전체 부의 80%를 가지고 있다는 파레토 법칙이 있다. 리뷰에서도 마찬가지다. 수강생의 20%가 전체 리뷰 시간의 80%를 가져간다.
Facts (사실, 객관)
역대급 리뷰수를 달성했다. 주고 받은 리뷰수가 94개였다.
코드를 리뷰할 때 동일한 내용은 중복해서 코멘트를 달지 않는다.(항상 리뷰를 반영하실 때 적용되는 부분이 또 있는지 확인해주세요!)
리뷰 퀄리티는 모두에게 동일하게 하려고 하지만 리뷰 시간은 동일 할 수 없다.
Feelings (느낌, 주관)
수강생분들이 읽을거리를 찾아와 질문을 하시면 나는 그 읽을거리를 모두 읽다보니 더 많은 걸 알아가게 되는 것 같다.
테스트 코드가 낯선 분들에게는 어떻게 더 조언을 드리면 좋을지 고민을 많이 해봐야겠다.
가끔 리뷰를 하다가 미리 알려줘 버리는 느낌을 받을 때가 있다. 스스로 찾을 수 있도록 완급 조절도 잘 해야겠다.
Findings (배운점)
테스트 코드를 작성할 때 React Testing Library 에서 screen 을 사용하는 것 보다 그냥 render 를 사용하는게 왜 더 나은지 개인적으로 생각해볼 기회가 있었다. screen 이 더 최신이지만 인터페이스적인 측면에서 오히려 더 별로인 것 같다는 생각이 들었다.
최신이라고 무조건 좋은게 아니다. 새로운 것을 도입할 때는 고민을 많이 해봐야한다.
React Testing Library 에 user-event 라는게 있다. 테스트에서 이벤트를 발생시키고 싶을 때 fireEvent 를 대체해서 사용할 수 있는데 조금 더 사용자의 관점에서 이벤트를 표현하는 점이 좋은 것 같다.
Mac은 기본적으로 Git 이 설치되어 있는데 버전도 낮고, 업그레이드 하려면 새로 다운로드를 받아야하는데 매번 이렇게 관리하는 것도 귀찮다. 그래서 맥북을 사용할 때 Homebrew 를 이용해서 대부분의 응용프로그램들을 관리하면 편하다. Git 도 마찬가지다
Homebrew 란? Homebrew 는 brew 라고 흔히 부르는데 MacOS 와 Linux 용 패키지 관리 매니저이다. brew 를 통해 패키지를 쉽게 설치하고 제거할 수 있다. 웬만한 프로그램은 다 있기 때문에 없는 것 빼고는 brew 를 통해 관리하는게 좋다. 프로그래밍을 할 때도 마찬가지지만 내가 통제할 수 있는 상태가 좋기 때문이다.
Git 설치
Homebrew 설치
Homebrew 가 설치되어 있지 않다면 먼저 설치하자. 아래 스크립트를 입력하면 자동으로 설치된다
$ /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
$ brew list --cask
Homebrew 를 이용해 Git 설치
간단하다. 설치하기 전후로 git 버전을 확인해보면 엄청나게 차이가 많이나는 걸 확인할 수 있다.
$ brew install git
$ git --version
Git 기본 설정
Git 을 설치했으면 사용하기 전에 기본적으로 세팅해주자. 설정은 설정 명령어를 통해 설정 파일을 읽고 쓰는 방식으로 바꿀 수 있다. 설정의 우선순위는 저장소 > 사용자 설정 > 시스템 이다. 처음에는 사용자 이름과 이메일 주소 정도만 설정해주면 된다.
# 이름 설정
$ git config --global user.name "Noah"
# 이메일 설정
$ git config --global user.email "noah@example.com"
# 설정 확인
$ git config --list
도움말 보기
# Git config 명령 도움말
$ git help config
# Git 명령어 도움말
$ git help
개발 프로젝트를 할 때 Git 을 많이 사용한다. 협업을 위해서도 사용하고, 개인으로 프로젝트를 관리하기 위해서도 많이 사용한다. 보통은 Git 의 사용법만 적당히 익힌 뒤 사용하는 경우가 많아서 Git 의 기능을 제대로 사용하지 못하거나 충돌같은 문제가 생기면 제대로 대응하지 못하는 경우가 많다. 그렇기 때문에 Git 에 대해 알고 사용하자.
Git 이란
Git 은 컴퓨터 파일의 변경사항을 추적하고 협업을 하기 위한 분산 버전 관리 시스템이다. Git 은 2005년에 리눅스 토발즈와 리눅스 커널 개발자들이 함께 개발 하였다. 2002년에 오픈소스 프로젝트 리눅스 커널은 BitKeeper 라고 하는 상용 분산 버전 관리 시스템을 사용하였다. 그런데 2005년에 BitKeeper 가 유료화가 되면서 리눅스 커널과의 관계가 틀어지고, 리눅스 토발즈와 개발자들이BitKeeper 를 사용하면서 배운 점을 바탕으로 Git 을 만든 것이다.
Git 의 목표
지금도 그렇고 Git 이 추구하는 목표는 다음과 같다.
빠른 속도
단순한 구조
비선형적인 개발(수천 개의 동시 다발적인 브랜치)
완벽한 분산
리눅스 커널 같은 대형 프로젝트에도 속도나 데이터 크기 면에서 유용할 것
버전 관리란
Git 에 대해 알기 위해서는 먼저 버전 관리에 대해 알아야 한다. 버전 관리 시스템(VCS, Version Control System)은 파일 변화를 시간에 따라 기록했다가 나중에 특정 시점의 버전을 다시 꺼내올 수 있는 시스템이다. 우리가 일상에서도 버전 관리 시스템을 쓰고 있는데 문서 되돌리기나, 포토샵에서 레이아웃 작업 이력 등도 모두 버전 관리 시스템이라 볼 수 있다. VCS 를 사용하면 각 파일을 이전 상태로 되돌릴 수 있고, 프로젝트를 통째로 이전 상태로 되돌릴 수도 있고, 시간에 따라 수정 내용을 비교해볼 수 있고, 누가 문제를 일으켰는지도 추적할 수 있고, 누가 언제 만들어낸 이슈인지도 알 수 있다. 또한 파일을 잃어버리거나 잘못 고쳤을 때도 쉽게 복구할 수 있다.
버전 관리 종류
로컬 버전 관리
VCS 는 로컬 버전 관리부터 시작된다. 로컬 버전 관리는 서버없이 내 컴퓨터에서 간단한 데이터베이스를 사용해 파일의 변경 정보를 관리하는 시스템이다. 버전을 관리하기 위해 디렉터리로 파일을 복사하는 방법을 사용할 수 있는데 이러면 디렉터리가 지워지거나, 실수로 파일을 수정하거나 잘못 복사할 수 있다. 이러한 이유로 프로그래머들에 의해 VCS 가 탄생하였다. 하지만 로컬 버전 관리는 말그대로 내 컴퓨터에서만 사용하기 위한 것으로 협업이 어려운 단점이 있다.
중앙집중식 버전 관리
중앙집중식 버전 관리(CVCS, Centrolized Version Control System) 는 파일을 관리하는 서버가 별도로 있고 클라이언트가 중앙 서버에서 파일을 받아서 사용(Checkout) 하는 시스템이다. 로컬 버전 관리로는 프로젝트 협업 등이 어렵기 때문에 만들어졌으며 Subversion(SVN) 같은 시스템이 대표적이다. 또한 관리자는 누가 무엇을 할지 관리할 수 있고, 모든 클라이언트의 로컬 데이터베이스를 관리할 필요 없이 VCS 하나를 관리하기 때문에 훨씬 쉽다. 하지만 CVCS 도 결점이 있는데 가장 대표적인 것이 중앙 서버가 다운되면 협업이 불가능하고, 백업할 방법도 없어진다. 그리고 중앙 데이터베이스가 있는 하드디스크에 문제가 생기면 프로젝트의 모든 히스토리를 잃는다.
분산 버전 관리 시스템
Git 과 같은 분산 버전 관리 시스템(DVCS, Distributed Version Control System)은 저장소를 전부 복제하는 방식의 시스템이다. 로컬 버전 관리나 중앙집중식 버전 관리의 결점들을 보완하여 클라이언트 중에서 아무거나 골라도 서버를 복원할 수 있고, 모든 Checkout 은 모든 데이터를 가진 진정한 백업이다. 대부분의 DVCS 환경에서는 리모트 저장소가 존재한다. 사람들은 동시에 다양한 그룹과 다양한 방법으로 협업할 수 있다. 계층 모델 같은 중앙집중식 시스템으로는 할 수 없는 워크플로를 다양하게 사용할 수 있다.
Git 의 특징
Subversion 이나 Perfoce 같은 것을 사용해봤다고 하면 개발한지 오래됐을 확률이 높다. Git 을 배우려면 SVN 등을 사용하던 경험을 버려야 한다고 하는데 작동 방식이 다르기 때문이다.
차이가 아닌 스냅샷을 저장한다
위에서 언급 했듯이 SVN 등과 Git 의 가장 큰 차이점은 데이터를 다루는 방법에 있다. SVN 등은 파일의 변화를 시간순으로 관리하면서 파일들의 집합을 관리한다. 즉 데이터 기반 관리 시스템인 것이다. 예를들어 1 + 2 + 3 을 쌓아 간다면 되돌아 가기 위해서는 -3, -2 로 역산해 나가야 한다. 대신 Git 은 시간순으로 프로젝트의 스냅샷을 저장한다. 파일이 달라지지 않았으면 Git 은 성능을 위해서 파일을 새로 저장하지 않는다. 단지 이전 상태의 파일에 대한 링크(레퍼런스 참고)만 저장한다. 그렇기 때문에 Git 은 한 달 전의 파일과 지금의 파일을 로컬에서 찾는다. 파일을 비교하기 위해 리모트에 있는 서버에 접근하고 나서 예전 버전을 가져올 필요가 없다. Git 은 데이터를 스냅샷의 스트림처럼 취급한다.
스탭샷(snapshot) 이란
컴퓨터 파일 시스템에서 스냅샷은 과거의 한 때 존재하고 유지시킨 컴퓨터 파일과 디렉터리의 모임이다. 스냅샷은 마치 사진을 찍듯이 특정 시점에 파일 시스템을 포착해 보관한다고 해서 붙여진 이름이다. 스냅샷은 원본 데이터를 그대로 복사해 다른 곳에 저장하는 백업과 달리 초기 생성 시 혹은 데이터의 변경이 있기 전까지는 스토리지의 공간을 차지하지 않는다.
거의 모든 명령을 로컬에서 실행한다
Git 은 거의 모든 명령이 로컬 파일과 데이터만 사용하기 때문에 네트워크에 있는 다른 컴퓨터는 필요 없다. 프로젝트의 모든 히스토리가 로컬 디스크에 있기 때문에 모든 명령이 순식간에 실행된다. “가장 빠른건 역시 localhost” 와 같은 이치다. 그래서 Git 에서 프로젝트의 히스토리를 조회할 때 서버가 필요없다.
Git 은 무결성을 보장한다
Git 은 데이터를 저장하기 전에 항상 체크섬을 구하고 그 체크섬으로 데이터를 관리한다. 체크섬은 Git 에서 사용하는 가장 기본적인(Atomic) 데이터 단위이자 Git 의 기본 철학이다. Git 은 SHA-1 해시를 사용하여 체크섬을 만든다. 만든 체크섬은 40자 길이의 16진수 문자열이다. 실제 사용할 때에는 줄여서 8글자만으로도 사용이 가능하다. 파일의 내용이나 디렉터리 구조를 이용하여 체크섬을 구한다. 실제로 Git 은 파일을 이름으로 저장하지 않고 해당 파일의 해시로 저장한다.
체크섬(checksum) 이란
체크섬은 자료의 무결성을 보호하는 단순한 방법이다. 데이터에 checksum 을 추가하여 연산을 통해 checksum 이 맞아 떨어지는지 확인해 봄으로써 데이터가 손상되지 않았다고 알 수 있다. 예를들면 위조 및 변조 방지를 위해 추가하는 주민등록번호 끝자리가 있다. 주민등록번호를 앞의 12자리 숫자에 각각 순서대로 2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5 를 곱한 뒤 모두 더한다. 그리고 더한 값을 11로 나눠서 나온 나머지 값을 11에서 뺀 숫자와 주민등록번호 끝자리가 같으면 유효한 것이다.
Git 은 데이터가 추가 되기만 할 뿐이다
Git 으로 한 것이면 무엇이든 Git 데이터베이스에 데이터가 추가된다. 데이터를 되돌리거나 데이터를 삭제할 방법이 없다. 되돌리기나 삭제를 하면 되돌리거나 삭제 했다는 내역을 추가할 뿐이다.
세 가지 상태
Git 은 Committed, Modified, Staged 이렇게 세가지 상태로 관리한다.
Committed: 데이터가 로컬 데이터베이스에 안전하게 저장됐다는 것을 의미, Git 디렉터리 단계
Modified 는 수정한 파일을 아직 로컬 데이터베이스에 커밋하지 않은 것을 의미, 워킹 트리 단계
Staged: 현재 수정한 파일을 곧 커밋할 것이라고 표시한 상태를 의미, Staging Area 단계
Git 디렉터리는 Git 이 프로젝트의 메타데이터와 객체 데이터베이스를 저장하는 곳을 말한다. Git 디렉터리가 Git 의 핵심이다. 다른 컴퓨터에 있는 저장소를 Clone 할 때 Git 디렉토리가 만들어 진다.
워킹 트리는 프로젝트의 특정 버전을 Checkout 한 것이다. Git 디렉터리는 지금 작업하는 디스크에 있고 그 디렉터리안에 압축된 데이터베이스에서 파일을 가져와서 워킹트리를 만든다.
Staging Area 는 Git 디렉터리에 있다. 단순한 파일이고 곧 커밋할 파일에 대한 정보를 저장한다.
Git 의 프로세스는 다음과 같다.
워킹 트리에서 파일을 수정
Staging Area 에 있는 파일을 Stage 해서 커밋할 스냅샷을 생성
Staging Area 에 있는 파일들을 커밋해서 Git 디렉토리에 영구적인 스냅샷으로 저장
Git 디렉토리에 있는 파일들은 Committed 상태이다. 파일을 수정하고 Staging Area에 추가했다면 Staged 이다. 주로 스테이지에 올린다고 표현한다. 그리고 Checkout 하고 나서 수정했지만, 아직 Staging Area에 추가하지 않았으면 Modified이다.
코딩(혹은 프로그래밍) 공부를 하다 보면 정작 우리가 당연히 사용하는 컴퓨터에 대해서는 기본 지식인 양 넘어가는 것들이 많다. 그래서 코딩(혹은 프로그래밍) 공부를 시작하기 전에 상식으로 알아두면 좋을 것들을 간단히 정리해 보았다.
컴퓨터에 대해여
컴퓨터라(computer)는 이름은 계산하는 기계라는 뜻으로 "계산하다(compute)"라는 동사에서 유래되었다.(항상 이름의 뜻을 잘 알아두자!) 이렇듯 컴퓨터는 인간의 연산을 돕기 위해 컴퓨터가 발명된 것이다.
프로그래밍 언어
우리가 영어나 한글을 사용하듯이 컴퓨터는 0과 1로 이루어진 이진수를 언어로 사용한다. 이를 기계어라고 한다.
세상에 인간의 언어가 다양하듯이 프로그래밍 언어도 다양하고, 지금 이순간에도 새로운 프로그래밍 언어들이 만들어지고 있다. 대략적인 프로그래밍 언어의 발전 흐름을 살펴보면 다음과 같다.
1세대: 기계어
2세대: 어셈블리어
3세대: C, 포트란, 베이직, 코볼 등
4세대: 비주얼베이직, 델파이, 파워빌더 등
5세대: 자바, C++, C#, ASP, PHP 등
여기서 어셈블리어는 기계어를 그나마 사람이 사용할 수 있도록 0101001 같은 숫자를 기호화 한 언어라고 볼 수 있다.
3세대 언어들은 주로 절차 지향 중심의 언어들인데 이때부터 프로그래밍 언어가 컴퓨터보다 사람에게 더 친숙하게 만들어지기 시작한다.
그래서 기계어, 어셈블리어를 저급언어(low-level), 이후의 언어들을 고급 언어(high-level)라고 한다.
4세대 언어들은 주로 데이터를 처리하기 위한 데이터베이스 관련 프로그램을 개발할 수 있는 언어들이다.(대부분 5세대 언어들에 의해 대체되고 있다.)
5세대 언어들은 객체지향 언어가 많고 또한 네트워크 관련 기능이 강화된 언어들이 많다.
최근에 많이 쓰이는 언어들은 대부분 5세대 언어라고 생각하면 된다.
컴퓨터는 어떻게 우리가 작성한 코드를 알아들을까
컴퓨터의 언어는 0과 1로 이루어진 기계어인데 어떻게 우리가 작성한 프로그래밍 언어(코드)를 인지하는 걸까?
위에서 언급했듯이 3세대 언어부터는 사람에 친화적인 프로그래밍 언어이기 때문에 컴퓨터가 프로그래밍 언어를 이해하기 위해서는 별도의 번역기가 필요하다.
비유하자면 컴퓨터에게 어셈블리어까지는 사투리라고 한다면 3세대 언어부터는 아예 외국어가 되는 것이다.
그렇기 때문에 코드(프로그램)가 컴퓨터에서 실행되기 위해서는 컴퓨터가 인식할 수 있는 기계어로 번역되어야 한다.
사람에 의해 작성된 코드는 번역기를 거쳐 기계어로 번역되고, 컴퓨터는 기계어로 작성된 코드들을 실행하는 방식이다.
번역하는 방법에는 크게 컴파일, 인터프리트가 있다.
컴파일
컴파일(compile)은 코드를 컴파일러(compiler)라는 것을 사용해 기계어로 번역한 다음 번역된 파일을 생성해 컴퓨터에서 실행시키는 방법이다.
여기서 컴파일러는 프로그래머에 의해 만들어진 소프트웨어이다.
컴파일의 장점은 한번 작성된 코드가 번역되어 실행 파일이 생성되면 이후로는 다시 번역할 필요 없이 번역된 실행파일을 실행시키면 되기 때문에 시간상의 효율성이 뛰어나다.
단점으로는 특정 시스템에서 번역된 실행 파일은 다른 시스템에서는 실행되지 않는다. 예를 들어 윈도우에서 번역된 파일은 맥에서는 실행되지 않기 때문에 각각 시스템에 맞는 컴파일러를 별도로 만들어 줘야 한다. (윈도우용과 맥용 프로그램이 따로 있는 이유가 여기에 있다!)
인터프리트
인터프리트(interpret)는 인터프리터(interpreter)라는 것을 사용해 코드를 직접 한 줄씩 번역한 다음 바로 실행시키는 방법이다. 한 줄씩 번역하여 실행시키기 때문에 매번 버그가 발생할 때마다 전체를 컴파일하지 않아도 돼서 디버깅에 편리하다.
또한 인터프리터만 있으면 컴파일 방법처럼 시스템마다 별도의 컴파일러가 필요한 방식이 아니라서 이식성이 뛰어나다.
주로 스크립트 언어들이 인터프리트 방법을 사용한다.
하지만 한 줄씩 번역하고 실행시키다 보니 전체를 기계어로 번역해서 실행시키는 컴파일 방법보다는 상대적으로 시간 효율성이 떨어진다.
최근에는 컴파일과 인터프리트 방법을 모두 사용하는 하이브리드 방식을 사용하고 , 하드웨어 성능이 높아져서 예전처럼 컴파일 언어와 인터프리터 언어의 성능 차이를 사람이 체감할 정도로 크지 않다.
하이브리드 방식은 사람이 작성한 코드를 컴파일러를 사용해 중간 코드(바이트 코드)로 변환하고 이 중간 코드를 가상 머신을 통해 한 줄씩 기계어로 번역하여 즉시 실행시키는 방식이다.
운영체제
운영체제(OS, Operating System)는 사용자가 컴퓨터를 편리하게 사용할 수 있도록 하드웨어 자원을 관리해주는 소프트웨어이다. 초기에는 컴퓨터 제작 회사별로 각자의 운영체제를 만들어 제공하였지만, 퍼스널 컴퓨터(PC)가 등장하고 나서부터는 일관된 형태의 운영체제가 사용되고 있다.
운영체제의 종류
DOS(Disk Operating System)
일명 도스로 불리며 퍼스널 컴퓨터가 처음 개발되었을 때 사용했던 운영체제이다. DOS는 명령어를 직접 입력하여 운영체제를 사용하는 CUI(Command-line User Interface) 형태의 운영체제이다. 맥에서 터미널이나 윈도우에서 콘솔 창이 이에 해당한다.
Windows 계열 운영체제
우리가 모두 그 Windows 다. Windows는 마우스로 편리하게 사용할 수 있는 GUI(Graphical User Interface) 방식의 운영체제로 1985년 마이크로소프트 사는 Windows 1.0 운영체제를 처음 발표하였다.
이후 Windows 1.0 ~ 3.0, Windows 95, Windows NT(New Technology), Windows 2000, Windows XP, Windows Vista, Windows 7 ~ 10 등이 계속해서 개발되었다.
Mac 운영체제
1984년 미국의 애플에서 매킨토시 계열의 퍼스널 컴퓨터나 워크스테이션에서 사용할 수 있는 Mac 운영체제를 개발하였다. Mac 운영체제는 마우스를 사용하는 최초의 GUI 형태의 운영체제이다.
유닉스(Unix) 계열 운영체제
1969년 미국의 AT&T사의 벨 연구소에서 개발된 운영체제로 주로 중대형 컴퓨터의 운영체제로 사용되었다. 1974년 데니스 매 캘리 스테어 리치(이름도 어렵다...)가 유닉스를 C 언어로 다시 개발하였고, 서로 다른 기종의 컴퓨터에도 유닉스가 쉽게 이식되어 사용될 수 있게 되었다. 그 이후 유닉스는 발전을 거듭하여 상용 운영체제인 솔라리스와 FreeBSD 유닉스를 탄생시켰다.
리눅스(Linux) 운영체제
1991년 핀란드 헬싱키 대학교의 학생인 리누스 토발즈에 의해 만들어진 운영체제로 유닉스를 PC에서 사용할 수 있게 만든 운영체제이다.
리눅스는 누구나 변환하여 사용할 수 있는 오픈소스이며, 개인용 컴퓨터 운영체제 또는 서버용 운영체제로도 많이 사용된다.
리눅스는 처음부터 소스코드를 공개하여 많은 사용자들로부터 유틸리티 소프트웨어가 만들어졌고, 배포판으로는 레드햇(Red Hat), 데비안(Debian) 등이 제공되고 있다.
스마트폰 운영체제
스마트폰에서 사용되는 운영체제로는 구글의 안드로이드, 애플의 iOS 등이 대표적이고 그 외 심비안, 블랙베리, 윈도우폰 7, 삼성의 바다 등이 있다.
데이터의 표현
이진수의 표현
컴퓨터는 0과 1로 구성된 이진수를 바탕으로 모든 데이터를 표현한다.
하나의 0이나 1을 비트(bit)라고 한다. 이진수를 사용하여 상태를 표현하면 두 가지 상태만 나타낼 수 있으므로 여러 개의 비트를 모아 하나의 상태를 표현한다.
문자의 표현
컴퓨터에서 사용하는 문자에는 영문자, 한글, 숫자, 특수 기호 문자 등이 있다.
초기의 컴퓨터에서는 컴퓨터마다 서로 다른 문자 코드 체계를 사용하여 프로그램의 호환성이 문제가 되었다. 이러한 호환성을 해결하기 위해 표준화된 코드체계가 필요했고, 그렇게 만들어진 대표적인 코드 체계로 아스키(ASCII) 코드와 유니코드(Unicode)가 있다.
아스키코드(ASCII, Amercian Standard Code for Information Interchange)
아스키코드는 영문 알파뱃을 사용하는 대표적인 표준 코드체계로 1967년에 표준으로 제정되었다.
아스키 코드는 7비트를 사용하여 표현하는 코드 체계로 33개의 제어 문자들과 공백을 포함하는 95개의 출력 가능한 문자로 구성되어 있다.
출력 가능한 문자들은 52개의 영문 알파벳 대소문자와 10개의 숫자, 32개의 특수 문자, 하나의 공백 문자로 이루어져 있다.
정규 표현식 리터럴은 스크립트가 불러와질 때 컴파일 된다. 그래서 정규 표현식이 상수일 때 성능이 더 좋다.
RegExp 객체의 생성자 함수를 호출하는 방법
const regex = new RegExp("no+ah");
생성자 함수를 사용하면 정규 표현식이 실행 시점에 컴파일 된다.
정규 표현식의 패턴이 변경될 수 있는 경우나 사용자 입력과 같이 다른 출처로 부터 패턴을 가져와야 하는 경우 생성자 함수를 사용한다.
자바스크립트에서 정규식 표현 패턴
자바스크립트에서 정규 표현식 패턴은 단순히 문자로 구성할 수도 있고 메타문자를 사용할 수도 있다.
단순 문자 패턴
단순히 문자로 구성하는 경우 /noah/ 로 작성하여 사용하면 문자열에서 noah 라는 부분의 문자열을 찾을 수 있다.
예를들어 "Who is noah?" 에서는 noah와 대응될 것이고, "Do you know Annah?" 에서 no 와 ah 가 부분적으로 포함되지만 noah의 형태가 정확히 포함되지 않기 때문에 대응되지 않는다.
메타문자를 사용한 패턴
자바스크립트에서 사용할 수 있는 메타문자들은 다음과 같다.
\ : 백슬래쉬는 문자 앞에 붙어 사용되는 경우 해당 문자는 글자 그대로 문자가 아닌 메타문자를 나타냄을 의미한다. 예를들어 정규 표현식에서 d 를 입력하면 소문자 그대로 d를 의미하지만 백슬래쉬를 앞에 붙여 \d 를 입력하면 숫자를 의미하는 메타문자가 된다. 반대로 백슬래쉬가 특수문자 앞에 붙어 사용되는 경우 특수 문자각 메타문자가 아닌 문자 그대로의 특수문자를 의미한다. 예를들어 /m*/ 은 m이 0번 이상 반복됨을 나타내는 정규 표현식이지만 /m\*/ 으로 작성하면 m* 문자를 의미한다.
^ : 입력의 시작 부분을 의미한다. /^m/ 이라고 입력하면 A로 시작하는 문자열에만 대응한다.
$ : 입력의 끝 부분을 의미한다. /m$/ 이라고 입력하면 m으로 끝나는 문자열에만 대응한다.
* : 앞에 입력된 문자가 0번 이상 반복됨을 의미한다. {0,} 으로도 표현할 수 있다. /no*ah/ 라고 작성하면 "nah" 또는 "nooooooah" 등과 대응 된다.
+ : 앞에 입력된 문자가 1번 이상 반복됨을 의미한다. {1,} 으로도 표현할 수 있다. /no+ah/ 라고 작성하면 "noah" 또는 "noooah" 등과 대응 된다.
? : 앞에 입력된 문자가 0번 또는 1번 나타남을 의미한다. {0,1} 으로도 표현할 수 있다. /no?ah/ 라고 작성하면 "nah" 또는 "noah" 만 대응 된다.
. : 개행 문자를 제외한 임의의 문자 하나를 의미한다. /.o/ 라고 작성하면 "This is a blog of noah" 에서 lo 와 no 와 대응 된다.
(text) : 여기서 괄호를 포획 괄호라고 부르며 문자열을 묶어서 대응시켜 준다. 예를들어 tistory noah 문자열에서 각각 tistory와 noah로 묶어서 나타내고 싶을 때 각 문자열을 /(\w+)\s(\w+)/ 와 같은 형식으로 대응 시켜 표현할 수 있다.
(?:text) : 비포획 괄호라고 하여 정규 표현식 연산자가 text 문자열 전체에 동작할 수 있게 하고 싶을 때 사용할 수 있다. 예를들어 /abc+/ 는 c가 반복되는 것을 나타냄으로 "abcabcabc" 에서 처음 abc에만 대응되지만 /(?:abc)+/ 라고 하면 abc 전체가 반복되는 것을 대응할 수 있다.
prefix(?=suffix) : suffix 가 뒤따라오는 prefix만 대응된다. 예를들어 noah(?=log|blog) 라고하면 noahlog 또는 noahblog 에 대응된다.
prefix(?!suffix) : suffix 가 뒤따라오지 않는 prefix 에만 대응된다. 예를들어 /\d+(?!\.)/ 은 소수점이 뒤따라오지 않는 숫자에만 대응되어 3.1417 이면 1417에만 대응된다.
x|y : x 또는 y 에 대응된다.
{n} : 앞 문자가 n번 나타날 경우 대응된다. (n은 양의 정수) /p{2}/ 이면 "apple" 에서 'pp'에 대응된다.
{n,m} : 앞 문자가 n번 이상 m번 이하일 경우에 대응된다. /o{2,3}/ 이면 "noooah" 에서 'ooo' 에 대응된다.
[text] : 문자셋(Character set)을 의미한다. [ ] 안에서는 점(.) 과 별표(*)도 단순 문자로 인식된다. 하이픈을 사용하면 범위를 지정할 수 있다. [ ] 안에서는 ^ 는 not 을 \b 는 백스페이스를 의미한다. 예를들어 /[a-z]/ 는 알파벳 전체 범위를 의미한다.
\b : 단어의 경계(시작이나 끝)을 의미한다.
\B : 단어의 경계가 아닌 곳(단어의 시작과 끝 사이)을 의미한다.
\cX : 문자열 내부의 제어 문자에 대응된다. X는 A ~ Z 까지의 문자 중 하나다.
\d : 숫자에 대응된다 [0-9]와 동일하다.
\D : 숫자가 아닌 문자에 대응된다. [^0-9]와 동일하다.
\f : 폼피드 문자에 대응된다.
\n : 줄 바꿈 문자에 대응된다.
\r : 캐리지 리턴 문자에 대응된다.
\s : 스페이스, 탭, 폼피드, 줄 바꿈 문자 등을 포함한 하나의 공백 문자에 대응 된다.
\S : 공백 문자가 아닌 하나의 문자에 대응된다.
\t : 탭 문자에 대응된다.
\v : 수직 탭 문자에 대응된다.
\w : 밑줄를 포함한 영숫자에 대응된다. [A-Za-z0-9_] 으로도 표현할 수 있다.
\W : 단어 문자가 아닌 문자에 대응된다. [^A-Za-z0-9_] 으로도 표현할 수 있다.
\숫자 : 정규 표현식 내부의 숫자 번째 괄호에서 대응된 부분에 대한 역참조
\0 : null 문자에 대응한다.
정규 표현식 플래그를 통한 검색
정규 표현식은 정규 표현식 패턴 구분자가 끝나는 곳에서 플래그를 추가해 줄 수 있다. 플래그는 각각 사용될 수도 있고 함께 사용될 수도 있다. 플래그 끼리의 순서에는 구분이 없다. 주로 많이 사용 되는 플래그는 다음과 같다.