정규식, 정규 표현식 regExp
2023. 5. 31. 14:16ㆍStudy/JavaScript
웹 개발을 하다보면 유저가 입력한 텍스트에 대해 검증해야 하는 경우가 있습니다.
대표적인 예시로 회원 가입시 비밀번호 입력을 들 수 있습니다.
‘영문 대문자, 소문자, 특수기호로 이뤄져야 한다.’ 등의 검증 로직을 정규식을 활용하여 구현할 수 있다.
정규식
정규 표현식, 또는 정규식은 문자열에서 특정 문자 조합을 찾기 위한 패턴입니다.
JavaScript에서는 정규 표현식도 객체로서, RegExp의 exec()와 test() 메서드를 사용할 수 있습니다.
String의 match(), matchAll() (en-US), replace(), replaceAll(), search(), split() 메서드와도 함께 사용할 수 있습니다.
정규 표현식 만들기
정규 표현식 객체를 생성하려면 정규 표현식 리터럴이나 RegExp 생성자 함수를 사용해야 합니다.
일반적으로는 정규 표현식 리터럴을 사용합니다.
정규 표현식 리터럴
- 다음과 같이 슬래시로 패턴을 감싸서 작성합니다.
- 정규 표현식 리터럴은 스크립트를 불러올 때 컴파일되므로, 바뀔 일이 없는 패턴의 경우 리터럴을 사용하면 성능이 향상될 수 있습니다.
// /(패턴)/i
const re = /ab+c/
RegExp 객체의 생성자 호출
- 생성자 함수를 사용하면 정규 표현식이 런타임에 컴파일됩니다.
- 바뀔 수 있는 패턴이나, 사용자 입력 등 외부 출처에서 가져오는 패턴의 경우 이렇게 사용하세요.
const re = new RegExp('ab+c')
플래그
플래그의 역할은 정규 표현식의 검색 방식을 설정합니다. 플래그에는 총 여섯가지가 있습니다.
플래그는 옵션입니다. 또한 순서와 상관없이 하나 이상의 플래그를 동시에 사용할 수도 있습니다.
flag | meaning | detail |
i | Ignore Casing | 대소문자 구별 없이 패턴 검사 |
g | Global | 패턴과 일치하는 모든 문자열 전역 검색 |
s | Dot All | .(온점)이 개행 문자(\n)도 포함 |
m | Multiline | 행이 바뀌어도 계속 검색 |
y | Sticky | 문자 내 특정 위치에서 검색을 시작 |
u | Unicode | 유니코드 전체 지원 |
d | 부분 문자열 일치에 대해 인덱스 생성 |
패턴
패턴은 / 로 열고 닫고 따옴표 " "는 생략합니다.
따옴표가 들어가면 따옴표까지도 패턴에 포함되어 검색해버립니다.
.
임의의 문자 한 개를 의미합니다. 문자의 내용은 상관없습니다. 단 \ 는 불가능합니다.
임의의 글자 수가 2개인 묶음의 배열을 반환하는 것을 볼 수 있습니다.
const text = 'I am a boy.';
const regExp = /../g;
console.log(text.match(regExp)); // ['I ', 'am', ' a', ' b', 'oy']
{}
수량 패턴입니다. 대괄호에 들어가는 값에 따라 개수에 다른 의미를 부여할 수 있습니다.
만약 그 숫자가 하나만 들어간다면 앞의 패턴이 그 수만큼 반복되는 문자열을 나타냅니다.
- 숫자가 {Min,Max}의 형태로 들어갈 수도 있습니다. 이 경우 최소, 최대 반복 횟수를 결정할 수 있는 것입니다. 주의할 점은 Min,Max사이에 공백이 없어야 합니다.
const text = '1 22 333 444';
const regExp = /3{3}/g;
console.log(text.match(regExp)); // [‘333’]
const text = '얍 얍얍얍 얍얍 얍 얍얍얍';
const regExp = /얍{2,3}/g;
console.log(text.match(regExp)); // [ '얍얍얍', '얍얍', '얍얍얍' ]
{Min,}의 형태를 가진다면 최소 개수 이상의 반복되는 패턴을 의미합니다.
const text = '얍 얍얍얍 얍얍 얍 얍얍얍';
const regExp = /얍{2,}/g;
console.log(text.match(regExp)); // [ ‘얍얍얍’, ‘얍얍’, ‘얍얍얍’ ]
+
최소 한 번 이상 반복되는 문자열을 의미합니다. 위에 설명한 {} 에서 {1,}과 같은 의미입니다.
const text = '얍 헐 얍얍 얍 얍얍얍';
const regExp = /얍+/g;
console.log(text.match(regExp)); // [ ‘얍’, ‘얍얍’, ‘얍’, ‘얍얍얍’ ]
[]
괄호 안에 제시한 문자들을 범위로 한 문자열을 의미합니다.
이를 응용하면 [a-zA-Z], [ㄱ-ㅎ가-
힣] 등을 통해 알파벳이나 한글 문자로 입력을 제한할 수 있습니다.문자 앞에 ^를 붙이면 특정 문자를 제외할 수 있습니다. 만약 [] 없이 사용한다면 특정 문자열로 시작하는 것을 의미합니다.
$
^이 문자열의 시작을 의미한다면 $는 반대로 문자열의 끝날 시점을 의미합니다.
정규식 메서드
위의 정규표현식을 가지고 이메일이나 전화번호 매칭 필터링을 하기 위해선 자바스크립트 정규식 메서드를 이용하여 패턴을 검사하고, 매칭되는 문자열을 추출, 변환한다.
정규표현식은 RegExp의 메서드 test()와 exec(),
String의 메서드 match(), replace(), search(), split() 에서 사용할 수 있습니다.
메서드 | 의미 |
match() | 캡처 그룹을 포함해서 모든 일치를 담은 배열을 반환합니다. 일치가 없으면 null을 반환합니다. ("문자열").match(/정규표현식/플래그) |
matchAll() | 캡쳐 그룹을 포함해서 모든 일치를 담은 반복기를 반환합니다. (en-US) |
search() | 문자여렝서 일치하는 부분을 탐색합니다. 일치하는 부분의 인덱스, 또는 일치가 없는 경우 -1을 반환합니다. |
replace() | 문자열에서 일치하는 부분을 탐색하고, 그 부분을 대체 문자열로 바꿔줍니다. ("문자열").replace(/정규표현식/, "대체문자열") |
replaceAll() | 문자열에서 일치하는 부분을 모두 탐색하고, 모두 대체 문자열로 바꿉니다. |
split() | 정규 표현식 또는 문자열 리터럴을 사용해서 문자열을 부분 문자열의 배열로 나눕니다. ("문자열").split(정규표현식) |
test() | 문자열에 이치하는 부분이 있는지 확인합니다. true 또는 false를 반환합니다. (정규표현식).test("문자열") |
exec() | 문자열에서 일치하는 부분을 탐색합니다. 일치 정보를 나타내는 배열, 또는 일치가 없는 경우 null을 반환합니다. const myRe = /d(b+)d/g; const myArray = myRe.exec('cdbbdbsbz'); |
문자열 내부에 패턴과 일치하는 부분이 존재하는지만 알아내려면 test()나 search() 메서드를 사용하세요.
더 느리더라도 일치에 관한 추가 정보가 필요하면 exec()과 match() 메서드를 사용하세요. 일치하는 부분이 존재하면, exec()과 match()는 일치에 관한 데이터를 포함한 배열을 반환하고, 일치에 사용한 정규 표현식 객체의 속성을 업데이트합니다. 일치하지 못한 경우 null을 반환합니다. (null은 조건 평가 시 false와 같습니다)
자주 사용하는 패턴
// 특정 단어로 끝나는지 검사
const fileName = 'index.html';
const regExp = /html$/;
// 'html'로 끝나는지 검사
// $ : 문자열의 끝을 의미한다.
// 숫자로만 이루어져 있는지 검사
const text = '12345';
const regExp = /^\d+$/;
// 모두 숫자인지 검사
// [] 바깥의 ^는 문자열의 처음을 의미한다.
// 아이디 사용 검사
// 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4~10자리인지 검사
const id = 'abc123';
const regExp = /^[A-Za-z0-9]{4,10}$/;
// 알파벳 대소문자 또는 숫자로 시작하고 끝나며 4 ~10자리인지 검사
// {4,10}: 4 ~ 10자리
// 핸드폰 번호 형식
const cellphone = '010-1234-5678';
const regexr = /^\d{3}-\d{3,4}-\d{4}$/;
// 웹사이트 주소 형식
// http:// 나 https://로 시작하고, 알파벳, 어더스코어(_), 하이픈(-), dot(.)으로 이루어져 있는 정규식
const text =
`http://dogumaster.com http://google.com 010-1111-2222 02-333-7777 curryyou@aaa.com`;
text.match(/https?:\/\/[\w\-\.]+/g); // ["http://dogumaster.com", "http://google.com"]
/*
1) http => 로 시작하고,
2) s? => 다음에 s는 없거나, 있고,
3) \/\/ => 다음에 특수기호 // 가 오고
4) [\w\-\.]+ => \w(영문자, 언더스코어), 하이픈, 쩜 으로 이루어진 문자열이 한개 이상(+) 있다.
5) g => 매칭되는걸 모두 다 찾는다.(플래그)
*/
// 전화번호 형식
// 유선번호라면 02-111-2222 형식이고, 핸드폰번호라면 010-1111-2222 형식을 모두 포함하는 정규식 (숫자의 갯수가 다름)\
const text =
`http://dogumaster.com http://google.com 010-1111-2222 02-333-7777 curryyou@aaa.com`;
text.match(/\d{2,3}-\d{3,4}-\d{4}/g); // [ '010-1111-2222', '02-333-7777' ]
/*
1) \d{2,3} => 숫자 2~3개로 시작하고,
2) \- => 다음에 하이픈(-)이 오고
3) \d{3, 4} => 다음에 숫자가 3~4개 오고,
4) \- => 다음에 하이픈(-)이 오고,
5) \d{4} => 다음에 숫자가 4개 온다.
6) g => 매칭되는걸 모두 다 찾는다(플래그)
*/
// 이메일 주소 형식
// xxx@xxxx.com 등의 형식
const text = `http://dogumaster.com http://google.com 010-1111-2222 02-333-7777 curryyou@aaa.com`;
text.match(/[\w\-\.]+\@[\w\-\.]+/g); // [ 'curryyou@aaa.com' ]
// 좀더 엄격한 검사가 필요하다면, 상황에 맞게 수정해서 사용면 된다.
const email = 'ungmo2@gmail.com';
const regexr = /^[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*@[0-9a-zA-Z]([-_\.]?[0-9a-zA-Z])*\.[a-zA-Z]{2,3}$/;
// 특수기호 정규표현식
// 모든 특수기호를 나열
const regex = /\[\]\{\}\/\(\)\.\?\<\>!@#$%^&*/g
// 문자와 숫자가 아닌것을 매칭
const regex = /[^a-zA-Z0-9가-힣ㄱ-ㅎ]/g
// 이밖의 정규표현식 모음
/* 전화번호 */
var localPhone = /^(0(2|3[1-3]|4[1-4]|5[1-5]|6[1-4]))(\d{3,4})(\d{4})$/;
var cellPhone = /^(?:(010\d{4})|(01[1|6|7|8|9]-\d{3,4}))(\d{4})$/;
/* 숫자 형식 */
var number = /[0-9]/;
var unsignedInt = /^[1-9][0-9]*$/;
var notNumber = /[^(0-9)]/gi;
/* 문자 형식 */
var korea_cv = /[ㄱ-ㅎ|ㅏ-ㅣ]/;
var korea = /[가-힣]/;
var koreaName = /[가-힣]/;
var english = /[a-z | A-Z]/;
/* 특문 */
var special_char = /[\{\}\[\]\/?.,;:|\)*~`!^\-+<>@\#$%&\\\=\(\'\"]/;
var comma_char = /,/g;
var blank = /[\s]/g;
/* 아이디 / 비밀번호 */
var id_check = /^[a-z | A-Z]{3,6}[0-9]{3,6}$/;
var password =/^.*(?=.{6,20})(?=.*[0-9])(?=.*[a-zA-Z]).*$/;
/* 이메일 형식 */
var email =/([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
/* 도메인 형식 */
var domain_all =/([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)
|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
var domain_include = /^((http(s?))\:\/\/)([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/;
var domain_exclude = /^[^((http(s?))\:\/\/)]([0-9a-zA-Z\-]+\.)+[a-zA-Z]{2,6}(\:[0-9]+)?(\/\S*)?$/;
/* 영문 한글만 */
var ko_en_num_charactor = /^[가-힣a-zA-Z0-9]*$/;
var ko_en_charactor = /^[가-힣a-zA-Z]*$/;
/* 자동차 번호판 */
var car = /^[0-9]{2}[\s]*[가-힣]{1}[\s]*[0-9]{4}$/;
var old_car = /^[가-힣]{2}[\s]*[0-9]{2}[\s]*[가-힣]{1}[\s]*[0-9]{4}$/;
정규식 테스트 사이트
https://regexr.com/
https://www.regexplanet.com/
https://regex101.com/
https://regexper.com/ (정규표현식을 그림으로 분석해줍니다)
자주 사용하는 정규 표현식 예제
참고:)
https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_expressions
https://pxd-fed-blog.web.app/regexp/
'Study > JavaScript' 카테고리의 다른 글
Javascript 네이밍(Naming)과 클린 코드(Clean Code) (0) | 2023.12.22 |
---|---|
Spread Operator (0) | 2023.12.22 |
웹, 앱 체크 navigator.userAgent (0) | 2023.04.06 |
ios mobile fix item + keypad 이슈 (0) | 2023.04.06 |
vanilla JS로 siblings 구현하기 (0) | 2023.02.13 |