JavaScript 정규표현식 수박 겉핥기😉

Harimad·2022년 8월 10일
0

js

목록 보기
4/14
post-thumbnail

0. 들어가며

이번 장에서는 자바스크립트의 정규표현식에 대해서 알아보겠습니다.
정규표현식은 자바스립트의 고유한 문법은 아닙니다.
대부분의 프로그래밍 언어에 내장되어있습니다.
그만큼 범용성이 있는 기능이며, 정규표현식을 잘 알고 있으면 문자 검색과 교체를 원하는 대로 조작할 수 있습니다. 이제 정규표현식에 대해서 얕게 알아보겠습니다.


1. 정규표현식이란?


1-1. 정의

정규 표현식(regular expression)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어이다. - 위키백과

  • 정규표현식은 내가 정한 조건과 일치하는 문자열을 탐색할 때, 패턴에 따라서 문자열을 일괄적으로 바꾸고 싶을 때 사용합니다.
  • 반복문과 조건문으로 문자열 변환을 하는 것보다 정규 표현식을 이용하면 원하는 대로 더 쉽게 문자열을 조작할 수 있습니다.

간단한 예시를 보겠습니다.

const filename = 'test.gif';

if (/\.jpg|\.png|\.gif/.test(filename)) {
  console.log('jpg/png/gif 파일이 맞음.');
} else {
  console.log('원하는 파일이 아님.');
}
//실행결과 : jpg/png/gif 파일이 맞음.

원하는 파일 형식을 찾을 때 정규표현식으로 찾으면 단 몇 줄이면 됩니다. 하지만 정규식을 사용하지 않는다면 어떻게 만들지 벌써부터 막막하기만 합니다.

1-2. 문법

정규 표현식은 패턴과 플래그로 구성되어 있습니다.
정규식 객체를 만들 때는 두 가지 방법이 있습니다.

① 첫 번째 방법

regexp = new RegExp('패턴', '플래그');

② 두 번째 방법

regexp = /패턴/; // 플래그 없음
regexp = /패턴/igmsuy; // 플래그 i, g, m, s, u, y 있음.

③ 두 문법의 차이점

두 문법의 차이점을 보면, /패턴/을 사용한 방법은 문자열 템플릿 리터럴에서 ${변수}를 한 것처럼 변수에 /패턴/을 넣을 수 없습니다. /패턴/은 정적이기 때문입니다.

반대로 첫 번째 방법인 new RegExp를 사용한 방법은 동적으로 생성된 문자열을 가지고 정규 표현식을 만들 때 사용할 수 있습니다.

let string = prompt('찾고 싶은 문자열이 무엇인가요?');
let regExp = new RegExp(`${string}`);

2. 플래그

자바스크립트에서 지원하는 플래그는 아래와 같습니다.

①. i - 대·소문자 구분 없이 검색합니다.
②. g - 패턴과 일치하는 모든 것을 찾습니다.
③. m - multiline mode의 약어로, 다중 행 모드를 활성화 시킵니다.
④. s - .이 개행 문자 \n도 포함하도록 'dotall'모드를 활성화 시킵니다.
⑤. u - 유니코드를 지원합니다.
⑥. y - 'sticky'모드를 활성화 시킵니다.


3. 메서드


3-1. String.prototype.replace()

replace() 메서드는 패턴에 일치하는 부분을 새로운 문자열로 반환합니다.

let str = 'Hello World, world, World';
let str2 = str.replace("World", "친구들");

console.log(str2); // Hello 친구들, world, World

정규표현식을 사용할 때

let str = 'Hello World, world, World';
let regExp = /World/gi; // 플래그 g는 모든 문자열에 해당, i는 대·소문자 구문하지 않음

console.log(str.replace(regExp, '친구들')); // Hello 친구들, 친구들, 친구들

3-2. String.prototype.match()

match() 메서드는 문자열이 정규식과 맞는 부분을 검색합니다.

// 문법
str.match(regexp)

매개변수

  • regexp는 정규식 개체입니다.
  • 정규식이 아닌 객체가 인자로 전달되면 new RegExp(객체)로 암묵적으로 사용합니다.
  • 매개변수를 빈값 match()으로 전달하면, 빈 문자열의 배열이 반환됩니다.

반환 값

  • 문자열이 정규식에 맞으면, 일치하는 문자열을 요소로 포함하는 배열을 반환합니다.
  • 만약 일치하는 것이 없다면, null을 반환합니다.
let str = '12345abcde6789fghi0';

// 정규식 일치
let regExp = /[a-z]{2}/g; // [a-z]{2}는 소문자 2자리
let result = str.match(regExp);

console.log(result); // (4) ['ab', 'cd', 'fg', 'hi']

// 정규실 불일치
let regExp2 = /hello/;
let result2 = str.match(regExp2);
console.log(result2); // null

3-3. String.prototype.search()

search() 메드는 정규식과 문자열 간의 일치함을 검색해 줍니다.

// 문법
str.search(regexp)
  • regexp는 정규식 객체 입니다.
  • 만약 정규식 객체가 인자로 전달 되지 않으면 암시적으로 new RegExp(regexp)처럼 변환됩니다.
  • 정규식과 주어진 문자열이 일치하는 인덱스를 반환 합니다. 만약 일치하는 항목이 없다면 -1을 반환합니다.
let welcome = 'Hello Word! This is JavaScript!';

// 정규식 일치
let regExp = /JavaScript/;
let result = welcome.search(regExp);

console.log(result); // 20

// 정규식 불일치
let regExp2 = /John/;
let result2 = welcome.search(regExp2);

console.log(result2); // -1

3-4. RegExp.prototype.test()

test() 메서드는 주어진 문자열이 정규식을 만족하는지 판별한 후 그 여부를 true/false로 반환합니다.

// 문법
regexpObj.test(str)
// str은 정규식 일치를 확인할 문자열 입니다.
let str = 'Hello World, world, World';

// 정규식 불일치
let regExp = /Helo/;

console.log(regExp.test(str)); // false

// 정규식 일치
let regExp2 = /Hello/;

console.log(regExp2.test(str)); // true

4. 예시

이제 정규표현식을 자주 쓰는 예시 2가지를 보도록 하겠습니다.
stackoverflow나 구글링을 하면서 전화번호나 이메일 정규식 패턴을 구문 이해 없이 복사·붙여넣기 한다면, 정규식에 대한 깊은 이해를 할 수 없습니다.
이번의 간단한 예시를 통해서 정규식에 대한 친밀감을 한발짝 다가갔으면 합니다.


4-1. 전화번호 패턴

let tel = '010-1234-5678';

let regExp = /^010-\d{4}-\d{4}$/;

console.log(regExp.test(tel)); // true
console.log(tel.search(regExp)); // 010
console.log(tel.match(regExp)); // ['010-1234-5678', index: 0, input: '010-1234-5678', groups: undefined]

정규식 설명


4-2. 이메일 패턴

let email = 'heung7min.son@gmail.com';
let wrongEmail = 'wrongWrong@gmail';
  
let regExp = /^([a-z]+\d*)+(\.?[a-z]+\d*)+@([a-z]+\d*)+(\.[a-z]{2,3})+$/;

console.log(regExp.test(email)); // true
console.log(regExp.test(wrongEmail)); // false

정규식 설명


4-3. 문제

/*
**	문제. 사용자가 입력한 아이디를 파라미터로 받고,
**	사용자 아이디가 다음 조건을 만족하는지 확인하는 함수를 작성하세요. (함수명: checkUserId(userId))
**
**	조건
**	1. [O] 사용자 아이디는 5자리 이상 15자리 이하입니다.
**	2. [O] 알파벳 소문자, 숫자, 밑줄(_), 마침표(.)만 포함할 수 있습니다.
**	3. [O] 밑줄은 연속해서 2개 사용할 수 없습니다.
**	4. [O] 마침표는 1개만 사용할 수 있습니다.
**	5. [O] 아이디 시작은 반드시 소문자여야 합니다.
**	6. [O] 아이디 마지막 문자는 소문자 또는 숫자만 가능합니다.
**	7. [O] 조건을 만족하면 true, 만족하지 않으면 false 반환하세요.
*/

function checkUserId(userId) {
	// ...
}
Answer 👈
function checkUserId(userId) {
  // 조건1
  const lenRegExp = /^.{5,15}$/;
  if (!lenRegExp.test(userId)) return false;

  // 조건 2
  const regExp = /[a-z0-9_\.]+/; // 언더바(_)는 \ 필요없음
  if (!regExp.test(userId)) return false;

  // 조건 2 (Way 2)
  // if (/[^a-z0-9\_\.]+/.test(userId)) return false; // [^~~~]는 ~~~의 부정이라는 말임

  // 조건 3
  const regExp2 = /_{2}/; // /__/g 할 필요없음
  if (regExp2.test(userId)) return false;

  // 조건 4
  if(userId.split('.').length > 2) return false;

  // 조건 5
  if(!/^[a-z]/.test(userId)) return false;

  // 조건 5 (Way 2)
  //if(/^[^a-z]/.teest(userId)) return false; // [^a-z]는 소문자가 아니면 이라는 뜻!
  
  // 조건 6
  if(!/[a-z0-9]$/.test(userId)) return false;

  return true;
}

// TEST CASES

// 여러 자릿수의 문자열
// 4자리 문자열
console.log(checkUserId('a234')); // false
// 5자리 문자열
console.log(checkUserId('a1234')); // true
// 15자리 문자열
console.log(checkUserId('a12345678901234')); // true
// 16자리 문자열
console.log(checkUserId('a123456789012345')); // false

// 알파벳, 소문자, 숫자, 밑줄(_), 마침표(.) 만 들어간 문자열
console.log(checkUserId('abcde')); // true
console.log(checkUserId('abcde1')); // true
console.log(checkUserId('ab.cde1')); // true
console.log(checkUserId('ab_cde1')); // true

// 알파벳, 소문자, 숫자, 밑줄(_), 마침표(.) 말고도 다른 문자가 들어간 문자열
console.log(checkUserId('a#bcde')); // false
console.log(checkUserId('abc^de')); // false
console.log(checkUserId('abc de')); // false

// 밑줄 1개 사용
console.log(checkUserId('abc_de')); // true

// 밑줄 연속 2개 이상 사용
console.log(checkUserId('abc__de')); // false
console.log(checkUserId('abc___de')); // false

// 밑줄 연속하지 않게 사용
console.log(checkUserId('a._1_b')); // true

// 마침표 1개 사용
console.log(checkUserId('abc.de')); // true
console.log(checkUserId('abcde.')); // true

// 마침표 2개 사용
console.log(checkUserId('abc..de')); // false
console.log(checkUserId('a.bc.d.de')); // false

// 시작이 소문자
console.log(checkUserId('abcde')); // true

// 시작이 소문자가 아닌 경우
console.log(checkUserId('Abcde')); // false
console.log(checkUserId('1bcde')); // false
console.log(checkUserId('.bcde')); // false
console.log(checkUserId('_bcde')); // false
console.log(checkUserId('@bcde')); // false

// 마지막 문자가 소문자 또는 숫자인 경우
console.log(checkUserId('abcde')); //true
console.log(checkUserId('abcd1')); //true
console.log(checkUserId('ab.cd1')); //true
console.log(checkUserId('ab.cd1')); //true
console.log(checkUserId('a_b.c_d1')); //true
console.log(checkUserId('a_b.c_.d1')); //false
console.log(checkUserId('a_b.c__d1')); //false
console.log(checkUserId('a_b.c_8_d1')); //true

// 마지막 문자가 소문자 또는 숫자가 아닌 경우
console.log(checkUserId('abcd.')); //false
console.log(checkUserId('abcd_')); //false
console.log(checkUserId('abcdA')); //false
console.log(checkUserId('abcd@')); //false

5. 마무리

  • 정리하면 정규표현식은 텍스트(문자열)에서 특정한 패턴을 찾아내는데에 사용되는 문자/기호 집합입니다.
  • 정규표현식은 문자열을 조작하는데 유용하지만, 시각적으로 보기에 한번에 이해하기 힘듭니다.
  • 그래서 어려운 개념으로만 받아들일 수 있습니다.
  • 정규식 패턴이나 문법들을 무조건 외우는게 능사가 아닙니다.
  • 정규식 문법들을 참고해서 원하는 문자열을 조작해내는 방법을 알고 있으면 충분하다고 생각합니다.
  • 정규 표현식에 관련한 메타 문자나 단축형 문자열 집합 등등의 문법은 아래 참고 링크를 들어가서 확인해주시길 바랍니다.

6. 참고

profile
Here and Now. 🧗‍♂️

0개의 댓글