| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 | 31 |
- Operating System
- 오퍼레이팅시스템
- 컴퓨터공학과
- c++
- 컴공과
- 정석학술정보관
- OS
- 문제풀이
- bfs
- 정석
- 오에스
- 너비우선탐색
- 스택
- 그래프
- 알고리즘
- cs
- 코딩
- vector
- 북리뷰
- 구현
- Computer science
- 백준
- 자료구조
- 컴공
- 개발
- Stack
- DP
- 코테
- 브루트포스
- coding
- Today
- Total
Little Jay
정규표현식(Regular Expression with Javascript) 본문
정규표현식이란?
정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다.
간단한 문자 검색부터 이메일, 패스워드 검사 등의 복잡한 문자 일치 기능 등을
정규식 패턴으로 빠르게 수행할 수 있습니다.
자바스크립트에서는 정규표현식 또한 객체입니다.
정규표현식의 역할
정규표현식은 크게 3개의 역할들로 구분합니다.
- 문자 검색(search)
- 문자 대체(replace)
- 문자 추출(extract)
본 포스팅은 자바스크립트의 정규식에대해 다루겠습니다.
파이썬, C++ 에서도 정규표현식을 지원하지만,
본 포스팅에서는 자바스크립트 기준으로 공부하고 정리한 것을 올리겠습니다
정규표현식 테스트 사이트
아래의 사이트들에서 간단하게 본인이 작성한 정규식코드를 확인할 수 있습니다.
https://regex101.com/
https://regexr.com/
https://regexper.com/
Regexper
regexper.com
그러나 주의하셔야할 점은, 각 사이트의 설정된 환경이 다르기 때문에 작동하지 않거나
자바스크립트에서 다루는 정규식과 다르게 작동할 수 있다는 것입니다.
사이트에서 테스트한 정규식의 결과를 맹신하지 말고 자신의 환경에 맞는지 테스트하시길 바라겠습니다.
정규식 생성
정규식은 두 가지 생성 방식이 있습니다.
- 생성자 방식
- 리터럴 방식
아래의 예시를 보면 생성자 방식은 RegExp 생성자 함수를 호출하여 사용할 수 있고,
리터럴 방식의 정규표현식은 /로 감싸진 패턴을 리터럴로 사용합니다.
//생성자
//const r1 = new RegExp('표현, '옵션')
const r1 = new RegExp('[a-z]', 'gi');
//리터럴
// /표현/옵션
const r2 = /[a-z]/gi;
보통의 경우 리터럴 방식이 선호 되지만 가끔 생성자 방식을 이용한 정규표현식을 작성해야할 떄도 있습니다.
정규식 속성 (Properties)
정규표현식에서는 유용하게 사용할 수 있는 속성들을 제공해줍니다.
| 속성 | 설명 |
| flags | 플래그 반환(String) |
| source | 표현식 반환(String) |
| global | 플래그 g 여부 반환(Boolean) |
| ignoreCase | 플래그 i 여부 반환(Boolean) |
| multiline | 플래그 m 여부 반환(Boolean) |
| sticky | 플래그 y 여부 반환(Boolean) |
| unicode | 플래그 u 여부 반환(Boolean) |
정규식에서 flags 옵션을 통해 값을 반환할 경우 그 값은 알파벳 순서대로 정렬되어 return 됩니다
new RegExp("^abc", "gi").flags;
// "gi"
/^abc/igy.flags;
// "giy"
표현식은 source 메서드를 사용합니다.
new RegExp("^abc", "gi").source;
// "^abc"
/^abc/igy.source;
// "^abc"
플래그 여부도 불린 형태로 파악이 가능합니다.
/^abc/igy.global;
// true
/^abc/igy.ignoreCase;
// true
/^abc/igy.unicode;
// false
JS 메서드와 정규식
JS에서는 기본적으로 정규식을 다루는 메서드들이 존재합니다. 아래의 표를 참고하시면 되겠습니다.
| 메소드 | 문법 | 설명 |
| exec | expression.exec(string) | 일치하는 하니의 정보(Array)를 반환 |
| test | 정규식.test(문자열) | 일치 여부(Boolean) 반환 |
| match | 문자열.match(정규식) | 일치하는 문자열의 배열(Array) 반환 |
| search | 문자열.search(정규식) | 일치하는 문자열의 인덱스(Number) 반환 |
| replace | 문자열.replace(정규식, 대체문자) | 일치하는 문자열을 대체하고 대체된 문자열(String) 반환 |
| split | 문자열.split(정규식) | 일치하는 문자열을 분할하여 배열(Array)로 반환 |
| toString | 생성자_정규식.toString() | 생성자 함수 방식의 정규식을 리터럴 방식의 문자열(String)로 반환 |
Lorem Ipsum 문장을 준비합니다.
const str = `Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged. It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.`;
.exec()는 다음과 같이 사용할 수 있습니다.
일치하는 결과가 없다면 null을 반환합니다.
/ipsum/.exec(str);
// null
/ipsum/i.exec(str);
// ["Ipsum", index: 6, input: "Lorem Ipsum is simply dummy text of the printing a…ldus PageMaker including versions of Lorem Ipsum.", groups: undefined]
정규식과 문자열의 순서를 바꿔서 작성하는 메소드 .match()는 다음과 같이 사용할 수 있습니다.
역시 일치하는 결과가 없다면 null을 반환합니다.
// 문자열.match(정규식);
str.match(/ipsum/);
// null
str.match(/ipsum/i);
// ["Ipsum", index: 6, input: "Lorem Ipsum is simply dummy text of the printing a…ldus PageMaker including versions of Lorem Ipsum.", groups: undefined]
플래그
플래그는 표현식의 옵션으로 표현식으로 검색하려는 문자 패턴에 추가적인 옵션을 넣어
원하는 문자 검색 결과를 반환하도록 할 수 있습니다.
사실 이 플래그가 무엇을 의미하고 있는지 모른다면 결과를 예상하기가 매우 어려워집니다.
위에서 살펴본 것처럼 플래그(flags)에 따라서 전혀 다른 결과가 나올 수 있습니다.
플래그도 플래그지만 사실 이 정규표현식이 어려운 이유는 낮선 특수기호들과
표현식의 패턴들 때문이지 않을까 싶습니다.
| 플래그 | 설명 |
| g | 모든 문자와 여러 줄 일치(global) |
| i | 영어 대소문자를 구분 않고 일치(insensitive, ignore case) |
| m | 여러 줄 일치(multi line) |
| u | 유니코드(unicode) |
| y | lastIndex 속성으로 지정된 인덱스에서만 1회 일치(sticky) |
g(global)
g 플래그는 가장 많이 사용되는 플래그 입니다.
str.match(/ipsum/i);
// ["Ipsum", index: 6, input: "Lorem Ipsum is simply dummy text of the printing a…ldus PageMaker including versions of Lorem Ipsum.", groups: undefined]
str.match(/ipsum/ig);
// (4) ["Ipsum", "Ipsum", "Ipsum", "Ipsum"]
ipsum이라는 문자를 검색하기 위해서 i flag를 사용했고, 이는 대소문자 상관없이 Ipsum을 검색하게 해줍니다.
첫 번째 match에서는 제일 첫번째 ipsum이 배열로 return 되는것을 확인할 수 있습니다.
두 번째 match에서는 g 플래그를 넣어 모든 ipsum을 배열형태로 return해주는 것을 볼 수 있습니다.
따라서 g가 없는 표현식은 하나의(최초의) 검색 결과만 반환했고
g가 있는 표현식은 모든 검색 결과를 배열로 반환했다는 것을 확인할 수 있습니다.
m(multi line)
const strML = `Lorem Ipsum is simply dummy text of the printing and typesetting industry.
Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.
It has survived not only five centuries, but also the leap into electronic typesetting, remaining essentially unchanged.
It was popularised in the 1960s with the release of Letraset sheets containing Lorem Ipsum passages, and more recently with desktop publishing software like Aldus PageMaker including versions of Lorem Ipsum.`;
이번에는 이렇게 Lorem Ipsum을 여러 줄로 나누어 넣어봤습니다.
strML.match(/$/g);
// [""]
strML.match(/$/gm);
// ["", "", "", ""]
아래에서 설명드리겠지만 표현식 $는 위 문장에서 ‘줄의 끝’을 검색하겠다는 의미입니다.
첫 번째 match는 문장을 하나로 처리했습니다.
그렇기 떄문에 전체 문장의 가장 끝부분이 검색되어 ‘빈 문자열’인 ""을 하나 반환하게됩니다.
반면 두 번쨰 match는 이 문장를 multiline으로 처리했기에 각 줄에서 끝부분을 검색하겠다는 의미로 사용됩니다.
따라서 총 3번의 줄바꿈과 함께 전체 문장의 가장 끝부분을 포함하여 총 4개의 결과를 반환합니다.
u, y 플래그는 제가 직접 많이 사용해보지 않아서 정리하지 않았습니다.
다른 블로그나 공식 문서 참고부탁드립니다.
정규식 패턴(표현식)
표현식에는 다양한 특수기호들이 존재합니다.
표현식들 자체가 많이 이질적이기 때문에 사용하실때 참조하시거나 외워두시는것을 추천드립니다.
자바스크립트 문법이 바뀌는 것에따라 표현식에도 추가되는것이 생기는데,
우선 많이 사용되는 표현식 위주로 정리하겠습니다. 이점 양해 부탁드리겠습니다.
| 정규식 패턴 | 설명 |
| ^ | 줄(Line)의 시작에서 일치, /^abc/ |
| $ | 줄(Line)의 끝에서 일치, /xyz$/ |
| . | 임의의 한 문자와 일치 |
| a|b | a 또는 b와 일치, 인덱스가 작은 것을 우선 반환 |
| * | 0회 이상 연속으로 반복되는 문자와 가능한 많이 일치, {0,}와 동일 |
| *? | 0회 이상 연속으로 반복되는 문자와 가능한 적게 일치(lazy), {0}와 동일 |
| + | 1회 이상 연속으로 반복되는 문자에 가능한 많이 일치, {1,}와 동일 |
| +? | 1회 이상 연속으로 반복되는 문자에 가능한 적게 일치(lazy), {1}와 동일 |
| ? | 없거나 1회 가능한 많이 일치 |
| ?? | 없거나 1회 가능한 적게 일치(lazy) |
| {3} | 3(숫자)개 연속 일치 |
| {3,} | 3개 이상 연속 일치 |
| {3,5} | 3개 이상 5개 이하(3~5개) 연속 일치 |
| {3,5}? | 3개 이상 5개 이하(3~5개) 연속 중 가능한 적은 3개 연속 일치(lazy), {3}와 동일 |
| () | 캡처(Capture)할 그룹 |
| (?<>) | 캡처 그룹 이름 지정, /(?<name>pattern)/ |
| \1~9 | 정규식 내 캡처된 값 참조, /(abc)\1/ |
| (?:) | 캡처(Capture)하지 않는 그룹 |
| (?=) | 앞쪽 일치(Lookahead), /ab(?=c)/ |
| (?<=) | 뒤쪽 일치(Lookbehind), /(?<=ab)c/ |
| [abc] | a 또는 b 또는 c와 일치, 점(.)이나 별표(*) 같은 특수 문자는 []안에서 특수 문자가 아님, /\.[.]/ |
| [a-z] | a부터 z 사이의 문자 구간에 일치(영어 소문자) |
| [A-Z] | A부터 Z 사이의 문자 구간에 일치(영어 대문자) |
| [0-9] | 0부터 9 사이의 문자 구간에 일치(숫자) |
| [가-힣] | 가부터 힣 사이의 문자 구간에 일치(한글) |
| [^abc] | a 또는 b 또는 c가 아닌 나머지 문자에 일치(부정) |
| \ | 이스케이프 문자 |
| \b | 63개 문자(영문 대소문자52개+숫자10개+_(언더스코어)가 아닌 나머지 문자에 일치하는 경계 |
| \B | 63개 문자에 일치하는 경계 |
| \d | 숫자(Digit)에 일치 |
| \D | 숫자가 아닌 문자에 일치 |
| \s | 공백(Space, Tab 등)에 일치 |
| \S | 공백이 아닌 문자에 일치 |
| \w | 63개 문자(Word, 영문 대소문자 52개 + 숫자 10개 + _)에 일치 |
| \W | 63개 문자가 아닌 나머지 문자에 일치 |
| \x | 16진수 문자에 일치, /\x61/는 a에 일치 |
| \0 | 8진수 문자에 일치, /\141/은 a에 일치 |
| \u | 유니코드(Unicode) 문자에 일치, /\u0061/는 a에 일치 |
| \c | 제어(Control) 문자에 일치 |
| \t | 탭 (U+0009) 문자에 일치 |
이 부분의 예제는 github 참조 부탁드립니다.
제가 적지못한 다양한 표현식들이 존재 가능합니다.
참고 자료 (References)
https://www.asciitable.com/
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/%EC%A0%95%EA%B7%9C%EC%8B%9D
https://flaviocopes.com/javascript-regular-expressions/
https://javascript.info/regexp-groups
https://heropy.blog/2018/10/28/regexp/
간단하게 제 github에도 올려져 있습니다.
https://github.com/MyuB/REGEXP_Study
훈수 지적 환영합니다.