[JS] 정규표현식 ( RegExp )

AREUM·2023년 2월 27일
0

Javascript이론

목록 보기
8/10
post-thumbnail

정규표현식 (RegExp : Regular Expression)

무엇이고 어느상황에 사용되는가 ?

문자열에서 특정 문자 조합을 찾기 위한 패턴이다.

input값의 value값을 가지고 사용자가 웹사이트에서 원하는 규율에 맞게 입력했는지 판단하는데에 사용이 된다.

대체적으로 사람들이 알고있는 로그인, 회원가입 등에서 사용되는데,
각 해당하는 입력칸에 맞는 규칙을 정해 놓고 그 규칙에 맞게 입력을 했는지 판단하고, 맞지않게 입력했을시에 규칙에 맞게 입력하라는 message를 나타나는 것을 볼 수 있다.

  • 사용자가 입력한 정보( 이름, 핸드폰번호, 이메일 등.. )가 정확한지 판단할 때
  • 특정 조건과 위치에 따라 입력값에 포함되어있는 공백, 특수문자를 제거하고 싶을 때

결론적으로 어느 상황에 사용되는지를 봤을 때
데이터의 값에 대해 원하는 조건에 맞게 필터링 할 때 많이 사용되는 것을 파악할 수 있다.

결론적으로

  • 문자 검색
  • 문자 대체
  • 문자 추출

테스트 사이트

https://regexr.com

정규식 코드 작성 방법

두 가지의 방법으로 작성할 수 있다.

  1. 리터럴 방식
  2. 생성자 함수를 이용한 객체 생성 방식
// 리터럴
const regex = /표현/옵션;
const regex = /[a-z]/gi;

// 생성자
const regex = new RegExp('표현', '옵션');
const regex = new RegExp('[a-z]', 'gi');

메소드 ( 추출, 변환 )

메소드를 이용해 해당 문자열의 패턴을 검사해 원하는 필터링 값으로 문자열을 추출, 변환하기 위해 사용된다.

메소드문법설명
match문자열.match(정규식)일치하는 문자의 배열 (Array)로 반환
replace문자열.replace(정규식, 대체문자)일치하는 문자를 대체문자로 변환
split문자열.slit(정규식)일치하는 문자를 항목으로 쪼개어서 배열(Array)로 반환
test정규식.test(문자열)일치 여부 (Boolean) 반환
exec정규식.exec.(문자열)match메소드와 동일 ( 단, 무조건 첫번째 매칭결과만 반환 )

맛보기

const regex = /yang/;
const text = "Hello my name is yang eille"

/* 문자열이 정규식과 일치하는 것이 있다면 Boolean값으로 반환해라. */
regex.test(text);	// true

/* 문자열이 정규식과 일치하는 것이 있다면 배열로 반환해라. */
text.match(regex);	// ['yang']

/* 정규식과 일치한 부분이 있으면 '대체문자열'로 변환해라. */
text.replace(regex, "yangsee"); // 'Hello my name is yangsee'

플래그(옵션) ( 검색 )

검색을 할 때, 기본 옵션이다.
기본 옵션을 ' 어떻게 설정해 둘 것인가? ' 환경설정이라고 생각하면 된다.

플래그설명
g문자열의 모든 패턴을 검색 (global)
i영어 대소문자를 구분 않고 검색 (ignore case)
m문자열의 행이 바뀌어도 검색 (multi line)

특징

g : 전역 검색

  • 플래그가 없으면, 최초 검색 결과를 한번만 반환
  • 플래그가 있다면 ? 모든 검색 결과를 배열로 반환

m : 줄 바꿈 검색

  • 여러 줄의 문자열을 필터링할 때 사용된다.

i : 대소문자 구분 없음

  • 정규식은 기본적으로 대소문자를 구분한다.
  • i 플래그를 사용하면 대소문자를 구분하지 않을 수 있다.

맛보기

const str = "Hello my name is Yang Eille";

/* g 플래그 */
str.match(/n/);		// ["n", index: 9, input: "Hello my name is Yang Eille", groups: undefined]
str.match(/n/g);	// (2) ["n", "n"]
// g를 사용했을 때와 사용하지 않았을 때의 차이점이다.

/* m */
const greet = "Good morning!\nHow old are you?\nfine Thank you.";
/*
Good morning!
How old are you?
fine Thank you.
*/
/* ^ : 문장의 시작점을 의미한다.*/

// 1. Good 단어로 시작하는지 검사.
greet.match(/^Good/);	// ["Good"]
// 2. How 단어로 시작하는지 검사
greet.match(/^How/);	// null
greet.match(/^How/m);	// ["How"]
// 두 번째 줄의 문장서는 How라는 단어로 시작하는지 검사했지만, null값이 나왔고 'm'을 사용해 How를 찾는다.
// 3. you라는 단어도 찾아보자.
greet.match(/you/gm);	// ["you", "you"]
// 모든 문장에 you라는 단어를 찾아낸다.

/* i 플래그 : 대소문자 구분하지 않게해라. */
str.match(/a/gi); // (2) ["a", "A"]
// `str`라는 변수안 문자열에서 a라는 알바벳이 대소문자 구분하지 않고 모두 반환해라.

패턴(표현) ( 대체 : 필터링 )

특정 문자, 숫자 매칭 패턴

패턴설명
[abc]a 또는 b 또는 c
[a-z]a 부터 z 사이의 문자 구간에 일치 (영어 소문자)
[A-Z]A 부터 Z 사이의 문자 구간에 일치 (영어 대문자)
[0-9]0부터 9 사이의 문자 구간에 일치 (숫자)
[가-힣]가부터 힣 사이의 문자 구간에 일치 (한글)
.모든 문자열 ( 숫자, 한글, 영어, 특수기호, 공백 모두 )
단, 줄바꿈 ❌
\d숫자(Digit)에 일치
\D숫자가 아닌 것
\w밑줄 문자를 포함한 영숫자 문자에 대응
즉, [A-Za-z0-9]와 동일하다.
\W\w의 반대. 즉, \w 가 아닌 것
\s공백(Space, Tab 등)
\S\s의 반대. 즉, 공백이 아닌 것
\b63개 문자에 일치하지 않는 문자
\B63개 문자(Word, 대소영문52개 + 숫자10개 + _)
\특수기호\*\^\&\?\! 등..

검색 기준 패턴

패턴설명
^ab줄(Line) 시작에 있는 ab와 일치
ab$줄(Line) 끝에 있는 ab와 일치
[ ]|(or) 의 묶음
[3-5] 3 or 4 or 5
[^ab]대괄호안 ^사용하면 대괄호안의 문자 제외.
"a", "b"를 제외
a|ba 또는 b와 일치 ( or )

객수 반복 패턴

패턴설명
ab?ab가 없거나 ab가 있거나 ( 최대 1개 일치 )
ab*ab가 없거나 ab가 있거나 ( 여러개 )
ab+ab가 최소 1개 or 여러개
*?없거나, 있거나 and 없거나, 최대 1개 : 없음
{0}와 동일
+?최소 1개, 있거나 and 없거나, 최대 1개 : 1개
{1}와 동일
{3}3개 연속일치
{3, }3개 이상 연속 일치
{3, 5}3개 이상 5개 이하 (3~5개) 연속 일치
{3,5}? == {3}과 동일

그룹 패턴

패턴설명
()그룹화 및 캡쳐
(?: 패턴)그룹화 ( 캡쳐 ❌ )
(?=)앞쪽 일치 ( Lookahead )
/ab(?=c)/
(?<=)뒤쪽 일치 ( Lookbehind )
/(?<=ab)c/
(?!)부정 앞쪽 일치 ( Negative Lookahead )
/ab(?!c)/
(?<!)부정 뒤쪽 일치 ( Negative Lookbehind )
/(?<!ab)c/

정규식 실습해보자.

프로그래머스의 정규표현식 강습을 들은 것을 정리했다.

const str = `
010-1234-5678
010 1234 5678
02 123 4567
031-123-4567
abcdef@gmail.com
https://www.google.com`
  • 최종
    주소록( 이름, 전화번호, 이메일 )에서 전화번호만 찾는 정규표현식
    : 0\d{1,2}[ -]?\d{3,4}[ -]?\d{3,4}

    어떻게 해서 이러한 정규표현식이 나왔는지 분석해보자.
  • 질문 : 010 1234 5678 전화번호를 구성하는 연결된 숫자를 찾을 때, 어떻게 해야하나 ?

  • 설명 :
    \d는 숫자를 한글자만 찾는다.
    +를 이용하면 된다.
    ( " +“하나 혹은 그 이상 연결된” 이라는 뜻이다. ” )

  • 결론 :
    \d+ => 하나 혹은 그 이상 연결된 숫자 를 의미한다.


  • 질문 : 010,1234,5678 중 자연수를 찾으려면 어떻게 해야하나 ?

자연수는

  • 0으로 시작하지 않는다.
  • 즉, 첫자리는 반드시 1 ~ 9 중에 하나이어야한다.
  • 그 다음 자리부터는 0 ~ 9 사이의 숫자가 나올 수도 있고, 나오지 않을 수도 있다.
  • 설명 :
    1. 처음에 1~9 중 하나의 숫자가 나온 다음
    2. 그 뒤에 숫자가 0개 이상 나오면 ?

  • 결론 :
    \d* : 숫자가 0개 이상이다 를 의미한다.
    ( “ *“0개 이상”이라는 뜻이다. “ )
    [1-9]\d => 첫 숫자가 0을 포함하지 않는다. 10,1234,5678 나온다.


  • 질문 :
    1. 전화번호는 “-“을 포함하거나 포함하지 않을수 있다.
    2. 모두 유효한 전화번호이다.

  • 설명 : 따라서 전화번호는 연속되는 숫자 3 ~ 4개 사이에 “-“가 있거나 없다고 표현할 수 있다.
    ?‘있거나 없거나’를 의미한다. “

  • 결론 :
    -?”는 “-가 있거나 없다” 를 의미한다.
    \d+-?\d+-?\d+ => 연속하는 숫자가 “-“가 있든 없든 숫자만 뽑아낸다.


  • 질문 :
    3번의 정규표현식에는 한계가 있다.
    공백이 포함된 전화번호를 찾아보아라.

  • 설명 :
    -?는 있거나 없다 라는 의미를 응용해서 공백도 추가해본다면,
    [- ]? ( 공백 또는 -이 있거나 없거나 를 의미한다. )

  • 결론 :
    \d+[- ]?\d+[- ]?\d+ => 하나이상 연결된 숫자들 사이에 “-“ 또는 공백이 있거나 없다.


  • 질문 : 010-7663-2800을 출력한다고 해보자.
    {숫자}는 “{숫자 번을 반복한다}”라는 뜻이다.
    \d{2} : ( 숫자가 연속 두 번 나온다. )

    ❗️ \d+[- ]?\d+[- ]?\d+ 에서 2개 3개 4개의 숫자가 연속으로 나오는것을 추가해본다.

  • 결론 :
    \d{3}[- ]?\d{4}[- ]?\d{4}


6.

5번의 답으로는 한계가 있다.
021234567
02-123-4567
010 1234 5678
이 경우에는 021234567와 02-123-4567은 찾지 못한다.

  • 질문 : 3개의 번호 모두 출력해야한다.

  • 설명 :
    {숫자1, 숫자2}“숫자1부터 숫자2까지 반복한다”는 뜻이다.

  • 결론 :
    \d{2, 3}[- ]?\d{3, 4}[- ]?\d{4}
    이렇게 한다면 모든 숫자를 출력할 수 있다.


  • 질문 : 알파벳 중에 소문자 모음만 고르고 싶을 땐 어떻게 해야하나 ?
  • 결론 :
    [aeiou] : 알파벳 소문자

  • 질문 : 소문자 알파벳만 고르고 싶을 땐 어떻게 할까 ?
  • 결과 : [a-z]

  • 질문 : 연속된 소문자 알파벳을 찾으려면 어떻게 해야할까 ?

  • 결과 : [a-z]+
    ❓ yangareum1818@nate.com
    👉🏻 yangareum, nate, com


  • 질문 : 한글 단어를 찾으려면 어떻게 해야할까 ?

  • 결과: [가-힣]+


언어 별 정규표현식

자바 ( Java )

  • Java로 정규식을 다룰 때에는 Pattern 클래스와 Mattcher 클래스를 이용한다.
  • 주의할 점 : Java에서는 escape 때문에 “\” 대신 “\\”를 적어야한다.
    \\d , \\w

씨샵( C# )

  • C# 에서는 자바와 동일하게 “\“ 대신 “\\“ 를 적어야한다.

파이썬 ( Python )

  • Python에서 raw string을 지원해 대표문자를 표현할 때에는 “\” 를 한번만 사용한다.

자바스크립트 ( Javascript )

  • Javascript로 정규표현식을 다룰 때에는 String classmatch 함수를 이용할 수 있다.
/* g는 global의 약자로, 정규표현식과 일치하는 모든 내용을 찾아오라는 옵션입니다. */
var regex = /\d/g;
console.log(searchTarget.match(regex));

  • Java === C#
  • Python === Javascript

다음은 정규표현식 실무에서 사용되는 유효성체크 하는 정규표현식 모음을 올려볼 생각이다.

도움받은 블로그
프로그래머스 정규표현식 실습

profile
어깨빵으로 부딪혀보는 개발끄적이는 양씨 인간

0개의 댓글