나에게 쓰는 기록들

현재 배우는 것이 무엇이든 글로 써서 기록을 남기는 것은 가치가 있다. - 소프트웨어 장인

JavaScript

내가 보려고 정리하는 JavaScript 정규식 사전

그리무 2021. 12. 18. 00:27

validation이나 폼과 관련된 여러가지 기능을 구현하다보면 정규식이 쓰일 때가 정말 많다. 그럴 때마다 구글링으로 내가 원하는 패턴의 정규식을 한 번 찾아보고, 찾은 다음엔 알맞은 정규식인지 확인하기 위해 정규식 레퍼런스를 찾아보고, 그런 다음엔 잘 동작하는지 테스트 코드를 짜보고, 테스트에 통과하지 않는 케이스일 경우 왜 그런지 이해하기 위해 또 찾아보고,,,, 이런 과정을 거친다. 이 과정을 조금 줄여보고자, 그리고 정규식에 더 익숙해지고자 이 글을 쓴다. 그리고 다음부터는 이 글만을 최대한 참고하면서 구현해보려 한다.

 

 

가능하려나,,,,? 🤣


 

정규 표현식(Regular Expression)은 문자열의 패턴을 표현하기 위한 도구이다. 정규 표현식을 사용하면 문자열 안에서 특정 패턴을 가지는 문자열을 검색/추출/치환하는 기능을 구현할 수 있다. 정규 표현식은 원래 유닉스의 스크립트 언어 처리(grep, sed, awk)에 사용되던 표기법이지만 현재는 Perl, Java, Javascript, PHP, Python, Ruby 등의 프로그래밍 언어에 내장되어 있다. 언어와 응용 프로그램 별로 기본적인 부분은 같지만, 세부적인 사양에는 차이가 있다고 한다.

자바스크립트의 정규 표현식은 Perl의 정규 표현식을 받아들인 것이며 ECMAScript 3부터 표준화되었다.

 

정규 표현식의 생성

정규 표현식은 RegExp 생성자 또는 정규 표현식 리터럴로 생성할 수 있다.

 

RegExp 생성자로 생성

var reg = new RegExp("abc");

 

정규 표현식 리터럴로 생성

var reg = /abc/;

 

위의 예제에서 abc 부분을 정규 표현식 패턴이라고 한다.

 

RegExp 객체의 메서드

자바스크립트로 정규 표현식을 사용해 문자열을 처리할 때는 RegExp.prototypetest, exec 메서드를 사용하거나 String.prototypematch, replace, search, split 메서드를 사용한다.

 

어떤 문자열이 정규 표현식과 일치하는지 확인하는 작업을 가리켜 패턴 매칭이라고 한다. RegExp.prototype의 test, exec 메서드를 사용하면 패턴 매칭을 수행할 수 있다.

 

  • test : 정규 표현식 문자열이 일치하는지에 대한 값을 boolean 값으로 반환한다.
  • exec : 정규 표현식과 일치하는 문자열을 배열로 반환한다. 못 찾았을 때는 null을 반환한다.
    • 반환된 배열 : [index(가장 처음 일치한 위치), input(일치한 문자열)]

 

리터럴 문자와 메타 문자

정규 표현식 패턴을 작성할 때는 일반 문자와 특수 문자를 사용할 수 있는데, 일반 문자는 리터럴 문자로, 특수 문자는 메타 문자로 표현한다.

  • 리터럴 문자 : 일반 문자, \0, \n, \t, \v, \f, \r, \xhh, \uhhhh, \cX
  • 메타 문자(정규 표현식의 구문 문자) : ^ $ \ . * + ? ( ) [ ] { } |

 

정규 표현식 패턴 작성

표기

  • 마침표(.) : 줄바꿈 문자를 제외한 임의의 문자 한 개와 일치한다.
  • \d : 숫자로 해석할 수 있는 문자 한 개와 일치한다.
    • d는 digit(아라비아 숫자)를 뜻한다.
    • [0123456789]의 단축 표기
    • \D는 그 반대로, [^0123456789]의 단축 표기이다.
  • \w : 모든 영어 단어 문자(알파벳, 숫자, 언더스코어) 한 개와 일치한다.
    • w는 word character라는 뜻이다.
    • [a-zA-Z0-9_]의 단축 표기
    • \W는 그 반대이다.
  • \s : 모든 공백 문자(공백 문자, 탭 문자, 개행 문자) 한 개와 일치한다.
    • s는 space라는 뜻이다.
    • \S는 그 반대이다.
  • \b : 영어 단어의 경계 위치와 일치한다.
    • \B는 그 반대이다.
  • ^ : 문자열의 시작 위치에 패턴을 고정한다.
    • 문자 클래스의 가장 앞부분에 표기한 ^은 부정을 뜻한다.
    • 여러 줄 검색(플래그 m)에서의 ^은 행의 시작을 뜻한다.
  • $ : 문자열의 마지막 위치에 패턴을 고정한다.
    • 여러 줄 검색(플래그 m)에서의 ^은 행의 끝을 뜻한다.

패턴

  • 문자 클래스 : [...]
    • [...] 안에 나열한 특정 문자 집합 중 문자 한 개와 일치한다.
    • 문자 클래스 안에서 하이픈(-)을 사용하면 문자의 범위를 지정할 수 있다.
    • $ . * + ? ( ) [ { } | 메타 문자를 문자 클래스 안에서 사용하면 메타문자로서의 의미를 잃고 그 문자 자체를 뜻하게 된다.
    • ] \ - 메타 문자를 원래 문자로 사용하고 싶다면 \ 문자를 앞에 붙여 이스케이프해야 한다.
  • 부정 문자 클래스 : [^...]
    • [...]의 여집합의 문자 한 개와 일치한다. (문자 클래스의 반대)
  • 반복 패턴
    • {m, n} : 바로 앞의 요소를 최소 m번, 최대 n번 반복한다.
    • {n,} : 바로 앞의 요소를 최소 n번 이상 반복한다.
    • {n} : 바로 앞의 요소를 n번 반복한다. {n, n}
    • ? : 바로 앞의 요소를 최소 0번, 최대 1번 반복한다. {0, 1}
    • \+ : 바로 앞의 요소를 최소 1번 이상 반복한다. {1,}
    • \* : 바로 앞의 요소를 최소 0번 이상 반복한다. {0,}
  • 그룹화 : (...)
    • 정규 표현식의 패턴 요소를 소괄호로 묶으면 부분적으로 그룹화할 수 있다.
    • 그룹화된 부분은 부분 정규 표현식이 된다. 이 부분 정규 표현식과 일치한 값은 별도로 저장(캡쳐링)되어 나중에 그 부분을 다시 참조할 수 있다.
  • 캡쳐링 없는 그룹화 : (?:...)
  • 전방 탐색 : (?=pattern)
    • x(?=y)라고 표기하면 x 다음에 y가 나오는 패턴이다.
  • 전방 부정 탐색 : (?!pattern)
    • x(?!y)라고 표기하면 x 다음에 y가 나오지 않는 패턴이다.
  • 선택 패턴 : |
    • /x|y|z/라고 표기하면 x, y, z 중에서 문자열 하나와 일치한다.

욕심 많은 반복과 욕심 없는 반복

욕심 많은 반복

/Java.*/.exec("I love Javascript");

위 구문의 결과는 ["Javascript"]이다. \*는 .(임의의 문자)를 가능한 최대 횟수만큼 반복해서 일치한 결과를 반환한다.

 

욕심 없는 반복

/Java.*?/.exec("I love Javascript");

위 구문의 결과는 ["Java"]이다. 반복 문자(\*) 뒤에 ?를 붙여주었다. 따라서 \*는 .(임의의 문자)를 최소한의 반복 횟수인 0번 반복한 결과를 반환한다.

 

주의 : /0*?1/를 문자열 "000012"에 매칭하면 "1"이 아닌, "00001"과 일치한다. 정규 표현식의 패턴을 검색할 때 문자열의 첫 번째 문자부터 검색하다가 일치하는 첫 번째 위치를 발견하면 그 결과를 반환하고 검색을 끝내기 때문이다. 그 다음에 등장하는 문자는 검색하지 않기 때문에 더 짧은 반복 패턴을 발견해도 모두 무시한다.

 

부분 정규 표현식 캡쳐링

var header = /<(h[1-6])>.*<\/\1>/;
console.log(header.test("<h1>JavaScript</h1>")); // true
console.log(header.test("<h1>JavaScript</h2>")); // false

console.log(header.exec("<h1>JavaScript</h1>"));
// ["<h1>JavaScript</h1>", "h1"]

 

\1은 첫번째 부분 정규 표현식을 참조한다. 위 예시는 HTML의 여는 태그와 닫는 태그가 서로 같아야 문법에 맞기 때문에, 그 부분을 검사하기 위한 것이다. 또한 이 때 exec 메서드를 사용하면 부분 정규 표현식과 일치한 문자열도 함께 배열로서 반환된다.

 

플래그

  • i : [case-insensitive] 대문자와 소문자를 구별하지 않는다.
  • g : [global] 전역 검색한다. (일치하는 모든 것을 검색한다.)
  • m : [multiple line] 여러 줄 모드로 검색한다.

 

💎


참고 자료

책 [모던 자바스크립트 입문]