정규 표현식

Taehun Jeong·2023년 2월 16일
0
post-thumbnail
post-custom-banner

개요

정규 표현식(Regular Expression)이란 문자열의 일정한 패턴을 표현하기 위해 사용하는 형식 패턴이다.


문법

메타 문자: 정규 표현식에서 특별한 의미를 갖고 쓰이는 문자로 위치를 지정하거나 순서, 패턴을 나타내는 데 쓰인다.

기호의미사용
.개행을 제외한 모든 문자열
^특정 문자열로 시작^문자열
$특정 문자열로 끝남문자열$
*특정 문자열 0개 이상 포함문자열*
+특정 문자열 1개 이상 포함문자열+
?특정 문자열 포함 (0개/1개)문자열?
[][]안의 문자들을 묶어서 처리[문자열]
()그룹화 및 캡쳐
{}반복 표현({n}이면 n회 반복, {n,}이면 n회 이상 반복 의미문자열{n}
{n,m}이면 n회 이상, m번 이하 반복 의미

문자 집합: 정규 표현식 내에서 검색을 쉽게 하기 위해 사용하며 매칭 패턴 등을 의미한다.

표현의미사용
^문자열의 제외를 의미[^문자열]
-문자와 문자 사이의 range를 의미, 그 range 사이의 문자에 해당[문자1~문자2]
\d숫자를 의미[0-9]와 동일
\D숫자 제외를 의미
\w숫자, 영문자, 밑줄 문자 의미[a-zA-Z0-9_]와 동일
\W\w에 해당되는 것의 제외 의미
\s공백 문자
\기호문자 그대로의 특수 기호 의미\*,\^,\$ 등
\b영어 대소문자+숫자 10개+(_)가 아닌 나머지 문자에 일치하는 경계
\B영어 대소문자+숫자 10개+(_) 문자에 일치하는 경계
\x16진수 문자에 일치
\08진수 문자에 일치
\u유니코드 문자에 일치
\c제어 문자에 일치
\f폼 피드 문자에 일치
\n줄 바꿈 문자에 일치
\t탭 문자에 일치
\v수직 탭 문자에 일치

플래그: 정규식을 생성할 때 검색 옵션을 위해 추가할 수 있다.

플래그의미
i대소문자의 구별 없이 검색함을 의미
g패턴과 일치하는 모든 것들을 검색함
m다중 행 모드 활성화. 문자열 내에서 개행이 있어도 검색을 계속함
s.(모든 문자 정규식)이 \n도 포함하도록 함
u유니코드 검색 지원
y문자 내 특정 위치에서 검색을 지원하는 'sticky' 모드 활성화

정규표현식 메서드

정규표현식을 이용하여 문자열이 정규표현식의 패턴을 따르는지, 그에 해당되는 문자열 패턴이 존재하는지, 또는 문자열 내에서 패턴에 매칭되는 문자열을 추출하는 등의 사용을 할 수 있다.

메서드기능
match문자열 내에서 정규표현식에 매칭되는 항목들을 배열로 반환
replace문자열 내에서 정규표현식에 매칭되는 항목들을 대체문자열로 변환
split문자열 내에서 정규표현식에 매칭되는 항목들로 나누어 배열로 반환
test문자열이 정규표현식과 매칭되면 ture, 그렇지 않으면 false
execmatch 메서드와 유사(첫번째 매칭 결과만 반환)
const regexp = /[0-9]/g; //문자열 전체의 0에서 9까지의 숫자들을 의미하는 정규표현식

console.log(regexp.test("ABCDE"));
//숫자가 포함되어 있지 않으므로 false
console.log(regexp.test("1ABCD"));
//숫자가 포함되어 있으므로 true

const txt = "I had 2 scoops of ice cream at Baskin Robbins 31.";
console.log(txt.match(regexp));
//배열 ['2', '3', '1'] 반환

응용

Baekjoon) 2671: 잠수함식별

const fs = require("fs");
const input = fs.readFileSync("/dev/stdin").toString().trim();

const regexp = /^(100+1+|01)+$/;
console.log(input.match(regexp) ? "SUBMARINE" : "NOISE");

정규 표현식을 사용한 첫 번째 알고리즘 풀이. 사용하는데 익숙지 않아 수 번의 시도 끝에 맞힐 수 있었다.
"100"의 패턴이 한 번 이상 반복되고 그 뒤에 "1"이 한 번 이상 쓰이는 패턴이 한 번 이상 있어야 하며, "01"로 끝나거나 그렇지 않은 패턴인지 검사하는 정규표현식을 사용한다.

회원가입 폼 만들어보기


사용자가 회원가입을 하려할 때, ID는 영문자로 시작하며 길이는 최소 5자 이상~최대 12자가 되도록, 비밀번호는 영문자, 숫자, 특수기호를 포함하여 최소 8자~최대 16자가 되도록, 이메일은 @를 포함하는 이메일 양식을 만족하도록 정규표현식을 작성해보자.

const idreq = /^[a-zA-Z]{1}[a-zA-Z0-9_]{4,11}$/;
const passwordreq =
    /^(?=.*[A-Za-z])(?=.*\d)(?=.*[~!@#$%^&*()+|=])[A-Za-z\d~!@#$%^&*()+|=]{8,16}$/;
const emailreq = /^[_a-z0-9-]+([._a-z0-9-]+)*@(\w+\.)+\w+$/;

id의 정규표현식은 영어 소문자, 대문자 중 1글자만 오면 되므로 ^를 사용해 시작 문자에 한하여, {1}로 1글자에만 [a-zA-Z]를 적용시킨다. 나머지는 4~11개의 영문자, 숫자가 쓰이도록 해주자.
비밀번호의 정규표현식은 ?=.* 를 사용했다. .*[]는 []안의 문자 중 임의의 하나를 의미한다. ?=는 positive lookahead라고도 불리며 정규식에서 매칭할 내용의 다음 또는 이전에 또 다른 정규식이 있는지 확인할 때 사용한다. lookaround라고도 불리는 기능으로 다음의 4종류가 있다.

표현타입의미
X(?=Y)Positive LookaheadX if followed by Y
X(?!Y)Negative LookaheadX if not followed by Y
(?<=Y)XPositive LookbehindX if after Y
(?<!Y)XNegative LookbehindX if not after Y

다소 고급 기능이고 이해하기 아직 어려웠지만, 한 번 적용해보았다. (?=.*[A-Za-z])(?=.*\d)(?=.*[~!@#$%^&*()+|=])은 각각 영문자를 적어도 하나 포함하는지, 숫자를 적어도 하나 포함하는지, 특수기호 ~!@#$%^&*()+|= 중 적어도 하나를 포함하는지를 검사하여 모두 만족할 경우 뒤의 정규표현식을 사용하여 검사한다.
이메일은 첫 부분에 영어 소문자, 숫자, 하이픈(-)과 언더바(_)가 첫번째로 오는지 확인하고 그 뒤에 영어 소문자, 숫자, -, _, . 있는지 확인한 후 @를 반드시 포함해야 하며, \w . \w의 형태로 도메인의 형식을 확인한다.


References

Inpa Dev) [JS] 📚 정규표현식(RegExp) - 이해하기 쉽게 정리 + 응용 예제
JAVASCRIPT INFO) 패턴과 플래그
Under The Pencil) 정규표현식 Lookahead, Lookbehind 기능 이해하기

profile
안녕하세요
post-custom-banner

0개의 댓글