본문 바로가기
개발/자바스크립트

[자바스크립트] 정규표현식(regex)에 대하여

by 핸디(Handy) 2021. 3. 1.

가끔씩 그럴 때가 있다. 특정 패턴을 지닌 문자열을 찾아내서 처리해야 하는 경우

let s = "my best stock is Apple";
s = s.replace("Apple","Tesla");
console.log(s) //my best stock is Tesla

근데 저렇게 정적인 문자열의 경우는 그냥 직접찾아서 바꾸면 되는데 만약 여러 종류라면 어찌할 건가?

이럴 경우에 필요한 것이 regular expression (regex)이다.

다음과 같이 전화번호들이 있다. 

let numberList = [
  "02-820-1111",
  "010-1234-1234",
  "010 1234 1234",
  "010.1234.1234",
  "aaa-bbbb-cccc",
  "0-1-1"
]

근데 보고 있자니 전화번호라는 것에 숫자 대신 이상한 값을 넣어준 빌런들이 있다. 

우리는 유효성을 검사해서 올바른 번호인지 아닌지 판별하고 싶다.

코드로 봐보자

let numberList = [
  "02-820-1111",
  "010-1234-1234",
  "010 1234 1234",
  "010.1234.1234",
  "aaa-bbbb-cccc",
  "0-1-1"
];

let regex=/[\d]{2,3}[-. ][\d]{3,4}[-. ][\d]{3,4}/;
let validList = numberList.map((item) => {
	return regex.test(item);
});

console.log(validList); // [true, true, true, true, false, false]

코드가 아주 멋져졌다. 내가 만든 regex는 다음과 같다

/[\d]{2,3}[-. ][\d]{3,4}[-. ][\d]{3,4}/

일단 자바스크립트에서 regex는 / expression/으로 쓴다.

[\d]{2,3} ->  숫자가 2개에서 3개

[-. ] -> - 또는 . 또는 스페이스

[\d]{3,4} -> 숫자가 3개에서 4개

의미가 다음과 같다. 보아하니 어렵지 않다.

하나를 더 해보자. 이번엔 이메일 관련 유효성이다.

let emailList = [
  "testEmail@naver.com",
  "testEmail&korea.co.kr",
  "2testEmail@gmail.com",
  "Test_Email@gmail.com",
];

let regex=/[a-zA-Z0-9]([._+-]?[a-zA-Z0-9])*@([a-z]+\.?)+/;
let validList = emailList.map((item) => {
	return regex.test(item);
});

console.log(validList); // [true, false, true, true]

이제 유효성 체크를 했다. 그럼 다음 작업을 추가로 진행해보자.

만약 이메일 주소가 유효하다면 그때 아이디를 뽑아오는 작업을 해보자.

let emailList = [
  "testEmail@naver.com",
  "testEmail&korea.co.kr",
  "2testEmail@gmail.com",
  "Test_Email@gmail.com",
];

let regex=/([a-zA-Z0-9](?:[._+-]?[a-zA-Z0-9])*)(?:@(?:[a-z]+\.?)+)/;
let validList =[]
emailList.forEach((item) => {
    if(regex.test(item)){
        validList.push(item.match(regex)[1])
    }
});
console.log(validList); // ["testEmail", "2testEmail", "Test_Email"]

아이디를 가져오기 위한 regex와 로직은 약간 바꿨다.

/[a-zA-Z0-9]([._+-]?[a-zA-Z0-9])*@([a-z]+\.?)+/
/([a-zA-Z0-9](?:[._+-]?[a-zA-Z0-9])*)(?:@(?:[a-z]+\.?)+)/

위의 두 regex는 패턴은 동일하나 아래의 경우에 (?: ) 가 추가됐다. 해당 문자의 의미는 grouping를 무시하겠단 의미이다.

잠깐 예제로 보자

let regex1=/([a-zA-Z0-9](?:[._+-]?[a-zA-Z0-9])*)(?:@(?:[a-z]+\.?)+)/;
let regex2= /[a-zA-Z0-9]([._+-]?[a-zA-Z0-9])*@([a-z]+\.?)+/;
let testEmail = "test@gmail.com"

testEmail.match(regex);
//["test@gmail.com", "test", index: 0, input: "test@gmail.com", groups: undefined]

testEmail.match(regex2);
// ["test@gmail.com", "t", "com", index: 0, input: "test@gmail.com", groups: undefined]

regex1 이 아이디를 가져오기 위한 것이다. 보면 배열에 값이 있는데 [matching string, group1, index, input. groups]의 순서로 들어온다.

우리가 grouping에 신경 쓰지 않은 regex2의 경우 t, com처럼 의미 없는 grouping이 생겼다. 

이를 통해 원하는 패턴에 일치하는 스트링에서 또 원하는 값을 뽑아올 수 있는 로직이 생기게 되었다.

 


[요약]

매번 javascript email regex라는 걸 검색해서 다른 사람이 만들어둔 regex를 사용하고 원하는 패턴을 찾을 때까지 인터넷을 찾아 헤매던 과거의 나를 반성하면서 이번 기회가 regex에 대한 기초적인 공부를 해봤다.

regex가 참 오묘한 게 대충 보면 어떤 느낌인지 오는데 어떤 걸 원하는 regex인가 했을 때 모르면 답할 수가 없다. 그만큼 최소한의 공부는 필요한 분야라고 생각한다.

내가 요새 보고 있는 채널 dream coding에서 20분짜리 강의가 있는데, 아주 멋지게 설명해주셔서 한번 보길 바란다.

dream coding --> www.youtube.com/watch?v=t3M6toIflyQ

그리고 가서 한번 풀어보자 -->  regexone.com/

그리고 다음에 내 regex를 점검해보자 --> regexr.com/5ml92

마지막 사이트의 경우 내가 원하는 regex를 쓰면 자동으로 설명해주고 색칠도 해주는 아주 갓갓사이트다.

위에서 만든 전화번호 regex를 넣으면 테스트와 아래 설명까지 된다. 갓갓

댓글