목적
구글 앱스 스크립트에서 정규식을 사용해 원하는 값을 얻는 방법을 이해합니다.
정규식(Regular Expression)이란?
정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다.
쉽게 말해서, 어떤 텍스트가 있는데 그 중에서 내가 원하는 텍스트를 추출하기 위해서 사용하는 규칙이라고 볼 수 있습니다. 잘 사용하면 계속 바뀌는 텍스트와 관계없이 원하는 텍스트 값을 얻어올 수 있는 장점이 있습니다.
구글 앱스 스크립트 활용 사례
프로젝트 중에 다음과 같은 여러 단계의 프로세스를 불연속적으로 처리해야하는 경우가 있었습니다.
1.
구글 스프레드 시트의 데이터로 구글 독스 문서 생성
2.
구글 독스 문서에 이미지 추가
3.
문서의 PDF 변환
4.
PDF의 이메일 전송
업무 자동화에서 위의 프로세스를 연속적으로 처리하는 경우가 많지만, 때에 따라서는 데이터가 아직 준비되어 있지 않거나, 수기로 수정하거나, 검수하기 위해서 불연속적으로 처리하기도 합니다.
연속적으로 처리할 때에는 스크립트를 실행할 때에 이메일 정보를 가지고 있다가 PDF를 만들고 이메일을 발송하는 것이 매우 쉽게 됩니다.
하지만 불연속적으로 진행하려면, 파일명에 이메일을 추가해두고 이메일을 추출해서 사용하거나, 코드를 추가해두고 코드를 추출한 뒤 이메일 정보와 매칭시켜야 합니다.
이러한 경우들에 정규 표현식이 유용하게 사용됩니다.
그럼 기본적인 정규 표현식 사용방법을 살펴보고, 이메일을 추출한 방법을 소개합니다.
기본적인 정규 표현식 사용방법
구글 앱스 스크립트에서는 new RegExp(표현식) 을 만들고, exec 를 붙여서 실행시킵니다.
다음과 같은 예제를 고려해보겠습니다.
function regexp1() {
let title_all = '[Category] Title - Description: This is test.'
//대괄호 안에 있는 항목 추출하기
let regexp_category = new RegExp('\\[(.*)\\]')
let category = regexp_category.exec(title_all)
Logger.log(category[1])
//]와 - 사이의 항목 추출하기 + 공백 제거
let regexp_title = new RegExp('\\](.*)-')
let title = regexp_title.exec(title_all)
Logger.log(title[1].trim())
//- 뒤에 있는 모든 항목 추출하기 + 앞 공백 제거
let regexp_desc = new RegExp('-.(.*)')
let description = regexp_desc.exec(title_all)
Logger.log(description[1])
}
JavaScript
복사
•
대괄호 안에 있는 항목 추출
먼저, 대괄호 안에 있는 항목을 추출하는 정규표현식을 정의해보겠습니다.
대괄호 안에 있어야 하니 먼저, [] 를 써줍니다.
대괄호 안에 있는 모든 텍스트를 추출할 것이기 때문에.* 을 써줍니다.
.은 개행 문자를 제외한 모든 단일 문자와 대응됩니다.
*은 앞의 표현식이 0회 이상 연속으로 반복되는 부분과 대응됩니다.
하지만, [.*]으로 정규표현식을 써주고 실행 시키면 값은 null 로 나오게 됩니다.
[ 와 ] 이 정규표현식 내에서 역할이 있기 때문에 그대로 사용하면 동작하지 않습니다. 때문에, 앞에 \\를 넣어주어 문자로 인식하도록 바꿔줍니다.
이제, \\[.*\\]를 넣으면 원하는 값을 얻을 수 있을까 싶지만, 여전히 null 이 나오게 됩니다.
.*를 괄호 ()로 씌워주어야 합니다.
최종적으로 정규표현식은 \\[(.*)\\] 이 되고, 결과는 Category 로 출력됩니다.
exec 는 배열을 반환하기 때문에 category[1] 로 써주어야 원하는 결과를 얻을 수 있습니다.
•
닫는 대괄호와 하이픈 사이에 있는 항목 추출 + 공백 제거
이번에는 Title 을 추출해보겠습니다. 이미 작성한 정규표현식에서 약간만 수정해주면 됩니다.
닫는 대괄호를 \\] 형식으로 써주고, (.*)을 써준다음 하이픈을 바로 써줍니다. 하이픈은 문자열로 바로 인식합니다.
실행시키면, 결과는 양쪽에 스페이스 공백이 들어가 있는 결과를 얻게 됩니다. Title
이제 trim()을 사용하면 원하는 결과를 얻을 수 있습니다.
•
- 뒤에 있는 모든 항목 추출하기 + 앞 공백 제거
이번에는 - 뒤에 있는 모든 항목을 추출하되, Description 앞의 공백은 제거하겠습니다.
아주 간단한데 하이픈 뒤에 온점만 넣어주시면 됩니다. 온점이 공백과도 대응하기 때문입니다.
이메일 추출 정규 표현식
이제 조금 복잡한 예제를 살펴보겠습니다. 실제 프로젝트에서도 사용했었는데요.
말씀드린 것처럼 불연속적인 프로세스에서 파일명에 이메일을 임시로 넣어두고, 나중에 발송하기 위해 추출하고, 발송하면서는 이메일부분을 삭제하였습니다.
function regexp2() {
let title_all = '[W0010]_Title_Description_S0001_email@gmail.com'
//대괄호 안에 있는 항목 추출하기
let regexp_category = new RegExp('\\[(.*)\\]')
let category = regexp_category.exec(title_all)
Logger.log(category[1])
//_와 _ 사이의 항목 추출하기 -> 첫번째
let regexp_title = new RegExp('\\]_(.*)_.*_S')
let title = regexp_title.exec(title_all)
Logger.log(title[1].trim())
//_와 _ 사이의 항목 추출하기 -> 두번째
let regexp_desc = new RegExp('\\]_.*_(.*)_S')
let description = regexp_desc.exec(title_all)
Logger.log(description[1])
//S0001 항목 추출하기
let regexp_code = new RegExp('_(S.*)_')
let code = regexp_code.exec(title_all)
Logger.log(code[1])
//이메일 항목 추출하기
let regexp_email = new RegExp('(?<=S.*_)(.*)')
let email = regexp_email.exec(title_all)
Logger.log(email[1])
}
JavaScript
복사
[W0010]_Title_Description_S0001_email@gmail.com 라는 파일명을 가진 경우, 가장 뒤에 있는 이메일을 추출하고자 합니다.
방법은 여러가지가 있지만, 후방탐색 기능을 사용한 예제입니다.
파일명이 모두 언더바 (_) 로 이어져있는 상태이기 때문에 단지 _(.*@.*) 라고 써준다면, Title_Description_S0001_email@gmail.com 을 결과로 얻게 됩니다.
후방탐색을 사용해서 S0001 뒤에 있는 이메일을 가져오도록 할 수 있습니다.
후방탐색의 구문은 ?<= 으로 정해져있습니다. S0001은 숫자가 변경될 수 있기 때문에 S.* 으로 구문화시키고, 언더바를 하나 붙여서 (?<=S.*_) 로 완성해줍니다.
그리고 최종 정규식을 (?<=S.*_)(.*) 으로 실행해주면, 원하는 이메일만을 추출할 수 있습니다.