TextFinder class 메소드 소개
2. TextFinder Class 알아보기
2.1 findAll()
2.2 findNext()
2.3 findPrevious()
2.4 matchCase()
2.5 matchEntireCell()
2.6 matchFormulaText()
2.7 replaceAllWith()
2.8 useRegularExpression()
1. 요약
이 포스트에서는 textFinder Class 의 다양한 메소드를 소개합니다. createTextFinder를 어떻게 사용하는지 알고 싶으시다면 다음의 연재 포스팅을 참조하실 수 있습니다.
Spreadsheet class의 createTextFinder()
Sheet class의 createTextFinder()
Range class의 createTextFinder()
2. TextFinder Class 알아보기
TextFinder의 메소드들을 체이닝 방식으로 호출하여 연결할 수 있습니다.
💡 체이닝 방식이란?
체이닝 방식은 한 줄에 여러 메소드 호출을 연결하는 것을 의미합니다. 메소드 호출 후 반환된 객체를 다음 연결된 메소드의 호출 대상으로 사용하지요. 중간 단계의 결과를 변수에 할당하지 않고도 메소드를 연속적으로 호출할 수 있기 때문에 코드가 간결해지며 가독성이 높아집니다.
예를 들어, 아래의 코드는 시트의 지정된 범위의 값을 가져오는 코드입니다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
function getDataFromSpreadsheet() { // 스프레드시트의 시트를 가져옵니다. const SPREADSHEET = SpreadsheetApp.getActiveSpreadsheet(); const SHEET = spreadsheet.getActiveSheet(); // 시트의 범위를 지정합니다. const range = sheet.getRange("A1:B5"); // 해당 범위의 값을 가져옵니다. const data = range.getValues(); // 가져온 데이터를 로그에 출력합니다. Logger.log(data); } |
이 코드를 체이닝 하면 어떻게 될까요?
1 2 3 4 5 |
function getDataFromSpreadsheet() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); const data = SHEET.getRange("A1:B5").getValues(); Logger.log(data); } |
스프레드시트를 불러오고, 활성화된 시트를 불러오는 코드를 1줄로 축약하였고, 데이터 범위를 지정하고 해당 범위에서 데이터를 가져오는 코드도 1줄로 줄였습니다. 이와 같이 체이닝 방식을 사용하면 코드를 간결하게 작성할 수 있으며, 연속적인 작업을 보다 쉽게 표현할 수 있습니다.
3.1 findAll()
설정한 범위 내에서 특정 텍스트와 일치하는 모든 텍스트를 찾고 Range를 배열 형식으로 반환합니다.
기본 사용 방법
1 2 3 4 |
function findText() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("찾고자 하는 텍스트").findAll(); } |
예시
아래의 고객 목록에서, ‘오토오피스’ 고객을 모두 찾기 위해 findAll()
을 사용해보겠습니다. 간단하게, 찾은 값의 위치를 Logger.log()
를 사용하여 로그에 출력해보겠습니다. 주의해야 하는 점은 findAll은 찾은 값의 범위를 배열 형식으로 반환한다는 점입니다.
코드
1 2 3 4 5 6 7 8 9 |
function findAll() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“오토오피스”).findAll(); textFinder.forEach(text => { let row = text.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요) }); } |
코드 설명
SHEET.createTextFinder("오토오피스").findAll()
: 가져온 시트에서 “오토오피스“라는 텍스트를 찾기 위해createTextFinder()
메소드를 사용하여TextFinder
객체를 생성합니다. 그런 다음findAll()
메서드를 사용하여 해당 텍스트를 포함하는 모든 요소를 찾습니다. 그 결과를textFinder
변수에 할당합니다.textFinder.forEach(text => { ... })
:
에는textFinder
에 의해 반환된 텍스트 검색 결과가 포함됩니다.findAll()
💡
메소드는 배열을 반환하기 때문에 배열을 순회하면서 각 요소를 처리해야 하므로 findAll()
forEach
를 사용합니다.
let row = text.getRow()
:text
변수는 각 텍스트 검색 결과(범위)를 나타냅니다.getRow()
메서드를 사용하여 해당 텍스트가 포함된 행 번호를 가져오고, 이를row
변수에 할당합니다.Logger.log()
: 로그에 텍스트 검색 결과를 기록합니다.
한번 스크립트를 실행해볼까요?
모든 값을 찾아냈고, 로그에 잘 저장되었습니다. 이제 findNext() 메소드를 살펴보겠습니다.
3.2 findNext()
이 메소드는 검색 기준과 일치하는 다음 셀을 반환합니다.
기본 사용 방법
1 2 3 4 5 |
function findNext() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("텍스트"); let foundCell = textFinder.findNext(); } |
예시
이번에는 아래의 고객 목록에서 ‘오토오피스’ 고객을 모두 찾기 위해 findNext()를 사용해보겠습니다. 찾은 값의 위치를 Logger.log()를 사용하여 로그에 출력해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 10 |
function findNext() { let SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("오토오피스"); let occurrence; while (occurrence = textFinder.findNext()) { let row = occurrence.getRow(); Logger.log(`검색 결과: ${row}행을 참조하세요`) } } |
코드 설명
SHEET.createTextFinder("오토오피스")
를 사용하여 “오토오피스”라는 문자열을 찾기 위한TextFinder
객체를 생성합니다.while
루프를 사용하여textFinder.findNext()
를 호출합니다. 이 메소드는 ‘오토오피스’ 문자열을 찾은 경우 해당 위치를 나타내는Range
객체를 반환합니다.- 루프 내부에서는 발견된 문자열의 위치를 나타내는
Range
객체에서 행 번호를 가져옵니다.getRow()
메소드를 사용하여 행 번호를 가져옵니다. - 가져온 행 번호를 로그에 출력하여 검색된 결과를 기록합니다.
스크립트를 실행해볼까요?
모든 값을 찾아내서 잘 출력하고 있습니다. 다음은, 반대로 findPrevious를 살펴보겠습니다.
3.3 findPrevious()
검색 기준과 일치하는 이전 셀을 반환합니다. findPrevious()는 검색 결과로부터 역방향으로 검색을 시작합니다.
기본 사용 방법
1 2 3 4 5 |
function findPrevious() { let SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("검색 텍스트"); let occurrence = textFinder.findPrevious(); } |
예시
이번에는 아래의 고객 목록에서 ‘오토오피스’ 고객을 모두 찾기 위해 findPrevious()를 사용해보겠습니다. 찾은 값의 위치를 Logger.log()를 사용하여 로그에 출력해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 10 |
function findPrevious() { let SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("오토오피스"); let occurrence; while (occurrence = textFinder.findPrevious()) { let row = occurrence.getRow(); Logger.log(`검색 결과: ${row}행을 참조하세요`); } } |
코드 설명
SHEET.createTextFinder("오토오피스")
를 사용하여 “오토오피스“라는 문자열을 찾기 위한TextFinder
객체를 생성합니다.while
루프를 사용하여textFinder.findPrevious()
메소드를 호출합니다. 이 메소드는 “오토오피스” 문자열을 찾은 경우 해당 위치를 나타내는Range
객체를 반환합니다.
💡 여기서 findPrevious()
는 ‘오토오피스’ 텍스트를 마지막부터 검색합니다. 그리고 반복문에 의해 2번째부터 findPrevious()
가 실행될 때에는 이전 검색 결과부터 역순으로 검색을 시작하므로 검색 결과 값이 findNext()
를 사용할 때와는 반대 방향으로 선언됩니다.
- 루프 내부에서는 발견된 문자열의 위치를 나타내는
Range
객체에서 행 번호를 가져옵니다.
메소드를 사용하여 행 번호를 가져옵니다.getRow()
- 가져온 행 번호를 로그에 출력하여 검색된 결과를 기록합니다.
스크립트를 실행해볼까요?
모든 값을 잘 찾아내고 있네요. 유의할 점은 findPrevious()를 사용하였기 때문에 마지막 검색 결과로부터 역순으로 결과 값이 출력되고 있다는 점이지요.
3.4 matchCase()
matchCase() 메소드는 텍스트를 찾을 때 대소문자를 구분할지 여부를 지정하는 불리언(boolean) 값입니다. 즉, matchCase(true)로 설정되면 검색할 때 대소문자를 구분하고, matchCase(false)로 설정되면 대소문자를 구분하지 않습니다. 기본적으로 matchCase(false)로 설정되어 있습니다.
기본 사용 방법
1 2 3 4 |
function matchCase() { let SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("텍스트").matchCase(true); } |
예시
아래 예시에는 ‘autooffice’와 ‘AUTOOFFICE’ 데이터가 존재합니다. findAll()메소드와 matchCase()를 활용하여 소문자 형식의 데이터만 찾아내보겠습니다. findAll에서 matchCase()옵션을 사용하지 않으면 기본적으로는 대소문자 구분 없이 모든 데이터를 찾아냅니다.
먼저, matchCase()를 사용하지 않고 findAll()을 사용하여 ‘autooffice’를 검색하면 어떤 결과가 나오는지 확인해보겠습니다.
1 2 3 4 5 6 7 8 9 |
function findAll() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“autooffice”).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요) }); } |
createTextFinder()는 기본적으로 matchCase를 사용하지 않아도 대소문자를 구분하지 않고 텍스트가 일치하는 값을 찾습니다. 아래의 로그를 보면 대소문자를 구분하지 않고 ‘autooffice’ 텍스트가 존재하는 모든 행 위치를 반환하고 있습니다.
이제 matchCase()를 활용하여 소문자로 기입된 ‘autooffice’ 값을 찾아보겠습니다.
코드
1 2 3 4 5 6 7 8 9 |
function matchCase() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“autooffice”).matchCase(true).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요) }); } |
코드 설명
createTextFinder("autooffice")
를 사용하여 텍스트 찾기 도구(TextFinder)를 생성합니다.matchCase(true)
를 호출하여 대소문자를 구분하여 검색하도록 설정합니다.findAll()
메서드를 호출하여 해당 텍스트를 포함하는 모든 셀을 찾습니다.forEach()
메서드를 사용하여 각각의 발견된 항목에 대해 반복하고, 각 항목의 행을 가져와 로그에 해당 행을 참조하는 메시지를 출력합니다.
스크립트를 실행해보겠습니다.
대문자로 입력되었던 ‘AUTOOFFICE’ 텍스트를 제외하고, 소문자로 입력된 ‘autooffice’ 데이터만 검색하였습니다.
3.5 matchEntireCell()
이 메소드는 텍스트를 찾을 때 셀 전체에 대해 일치 여부를 결정하는 옵션을 설정합니다. 기본적으로 matchEntireCell(false)로 설정되어 있습니다. 따라서 기본적으로 텍스트를 찾을 때 셀 전체에 대한 일치 여부를 고려하지 않고 텍스트의 일부분만 일치 여부를 판단합니다. 전체 텍스트가 일치하도록 조건을 주기 위해서는 matchEntireCell(true)로 설정해야 합니다.
기본 사용 방법
1 2 3 4 |
function matchEntireCell() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("텍스트").matchEntireCell(true); } |
예시
아래 코드에는 ‘오토오피스’,’오토오피스2’,’오토오피스3’ 데이터가 존재합니다. 옵션에 따라 ‘오토오피스’라는 단어가 포함된 셀을 검색할 수도 있고, ‘오토오피스’라는 단어가 셀의 전체 내용과 일치하는 셀을 검색할 수도 있습니다.
먼저, matchEntireCell()를 사용하지 않고 findAll()을 사용하여 ‘오토오피스’를 검색하면 어떤 결과가 나오는지 확인해보겠습니다.
1 2 3 4 5 6 7 8 9 |
function findAll() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“오토오피스”).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요) }); } |
createTextFinder()는 기본적으로 텍스트가 포함된 셀을 찾아오기 때문에 아래와 같이 ‘오토오피스’ 텍스트가 포함되어있는 모든 셀을 찾습니다.
이제 matchEntireCell()를 활용하여 ‘오토오피스’ 텍스트와 셀이 정확히 일치하는 데이터만 찾아보겠습니다.
코드
1 2 3 4 5 6 7 8 9 |
function matchEntireCell() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“오토오피스”).matchEntireCell(true).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요) }); } |
코드 설명
createTextFinder("오토오피스")
를 사용하여 텍스트 찾기 도구(TextFinder)를 생성합니다.matchEntireCell(true)
를 호출하여 해당 텍스트가 셀 전체에 정확히 일치해야만 해당 셀이 반환되도록 설정합니다.findAll()
메서드를 호출하여 해당 텍스트를 포함하는 모든 셀을 찾습니다.TextFinder.findAll()
이 호출되고, 해당 텍스트를 포함하는 모든 셀의 위치를 반환합니다.forEach()
메서드를 사용하여 각각의 발견된 항목에 대해 반복하고, 각 항목의 행을 가져와 로그에 해당 행을 참조하는 메시지를 출력합니다.
스크립트를 실행해보겠습니다.
‘오토오피스’ 텍스트와 정확히 일치하는 값만 출력하였습니다.
3.6 matchFormulaText()
이 메소드는 텍스트를 찾을 때 셀이나 범위의 수식에 대한 일치 여부를 결정하는 옵션을 설정합니다. 기본적으로 matchFormulaText(false)로 설정되어 있습니다. 따라서 기본적으로 텍스트를 찾을 때 셀의 값만 고려하고, 수식 텍스트는 고려하지 않습니다.
기본 사용 방법
1 2 3 4 |
function matchFormulaText() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("수식").matchFormulaText(true); } |
예시
아래의 예시에서 A12 셀에는 ‘=TODAY()’라는 수식이 입력되어 있습니다. matchFormulaText()를 활용하면 수식이 사용된 셀을 검색할 수 있습니다.
이제 matchFormulaText()를 사용하여 수식을 검색해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 |
function matchFormulaText() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“TODAY()”).matchFormulaText(true).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요); }); } |
코드 설명
createTextFinder("TODAY()")
를 사용하여 텍스트 찾기 도구(TextFinder)를 생성합니다. 여기서 “TODAY()”는 검색할 수식입니다.matchFormulaText(true)
를 호출하여 해당 텍스트가 셀의 수식에 일치하는 경우에만 해당 셀이 반환되도록 설정합니다.
💡 matchFormulaText()
메소드는 기본적으로 검색하고자 하는 수식이 포함되는 모든 셀을 검색합니다. 만약 검색하고자 하는 수식과 시트의 수식이 정확히 일치하는 셀을 찾기 위해서는 다음 코드와 같이 matchEntireCell(true)
옵션을 추가해주어야 합니다. 이 경우에는 검색 수식에 ‘=’(등호)도 입력해주어야 합니다.
1 2 |
let textFinder = SHEET.createTextFinder("수식") .matchFormulaText(true).matchEntireCell(true).findAll(); |
findAll()
메소드를 호출하여 해당 텍스트를 포함하는 모든 셀을 찾습니다.TextFinder.findAll()
이 호출되고, 해당 텍스트를 포함하는 모든 셀의 위치를 반환합니다.forEach()
메서드를 사용하여 각각의 발견된 항목에 대해 반복하고, 각 항목의 행을 가져와 로그에 해당 행을 참조하는 메시지를 출력합니다.
스크립트를 실행해볼까요?
=TODAY() 수식이 사용된 셀의 위치만을 찾아서 반환하고 있습니다.
💡 여기서 잠깐! 수식으로 입력된 값도 TextFinder로 검색이 가능할까요? 간단한 예시를 보겠습니다. ‘C1’ 셀에는 ‘A1+B1’이라는 수식에 의해 ‘2’라는 값이 출력되었습니다.
테스트를 위해 TextFinder로 ‘2’를 검색해보겠습니다.
1 2 3 4 5 6 7 8 9 |
function findAll() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(“2”).findAll(); textFinder.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요); }); } |
로그를 살펴보니 수식에 의한 결과 값도 TextFinder를 통해서 검색이 가능하다는 것을 알 수 있습니다.
3.7 replaceAllWith()
replaceAllWith() 메소드는 텍스트를 찾은 후에 해당 텍스트를 지정된 다른 텍스트로 모두 대체하는 기능을 제공합니다. 괄호안에 대체할 새로운 텍스트를 입력합니다. 메소드가 실행된 후에는 변경된 셀의 수가 반환됩니다.
기본 사용 방법
1 2 3 4 5 |
function replaceAllWith() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder("찾을 텍스트"); textFinder.replaceAllWith("대체할 텍스트"); } |
예시
아래 예시에서 ‘autooffice’ 라는 이름을 찾아서 ‘오토오피스’로 변경하는 코드를 작성해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 10 11 |
function replaceAllWith() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(‘autooffice’); let replacedCount = textFinder.replaceAllWith(‘오토오피스’); if (replacedCount => 0) { Logger.log( ${replacedCount}개의 값이 변경되었습니다.); } else { Logger.log(“변경된 값이 없습니다.”); } } |
코드 설명
createTextFinder('autooffice')
를 사용하여 TextFinder를 생성합니다. 여기서 ‘autooffice‘는 대체하고자 하는 텍스트입니다.replaceAllWith('오토오피스')
를 호출하여 “autooffice“를 “오토오피스“로 모두 대체합니다. 이때, 변경된 셀의 수가 반환됩니다.
💡 replaceAllWith()
메소드는 주어진 범위에서 일치하는 모든 항목을 찾아서 교체합니다. findAll()
옵션을 기본으로 사용하고 있는 것과 같은 것입니다.
- 반환된 변경된 셀의 수를 변수
replacedCount
에 저장합니다.
가 0보다 큰 경우, 변경된 셀이 있으므로 변경된 셀의 수를 로그에 출력합니다.replacedCount
가 0인 경우, 변경된 셀이 없으므로 “변경된 값이 없습니다.”를 로그에 출력합니다.replacedCount
스크립트를 실행해보겠습니다.
‘autooffice’ 텍스트가 모두 ‘오토오피스’로 변경되었습니다. 다음은 정규 표현식을 검색하는 메소드를 소개하겠습니다.
3.8 useRegularExpression()
이 메소드는 정규 표현식을 사용하여 텍스트를 검색하는 기능을 제공합니다.
기본 사용 방법
1 2 3 4 |
function findTextInRange() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder('정규표현식').useRegularExpression(true); } |
예시
아래 예시에서 정규 표현식을 사용하여 이메일이 입력된 사람들의 행 위치를 출력해보겠습니다.
코드
1 2 3 4 5 6 7 8 9 |
function useRegularExpression() { const SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet(); let textFinder = SHEET.createTextFinder(‘^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$’).useRegularExpression(true); let foundCells = textFinder.findAll() foundCells.forEach(occurrence => { let row = occurrence.getRow(); Logger.log( 검색 결과: ${row}행을 참조하세요); }); } |
코드 설명
- 먼저
SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
를 사용하여 현재 활성화된 스프레드시트의 시트를 가져옵니다. createTextFinder('^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$')
를 사용하여TextFinder
객체를 생성합니다. 여기서 사용된 정규 표현식은 이메일 주소의 형식을 따릅니다.
💡 위 정규 표현식에 사용된 문자들은 무엇을 의미할까요?
: 하나 이상의 영문자, 숫자, 점(^[a-zA-Z0-9._%+-]+
.
), 밑줄(_
), 퍼센트(%
), 플러스(+
), 또는 하이픈(-
)을 포함합니다.
: ‘@’ 기호를 나타냅니다. 이메일의 필수 요소지요.@
: 도메인 이름은 영문자, 숫자, 점, 또는 하이픈을 포함할 수 있습니다.[a-zA-Z0-9.-]+
: 점(\.[a-zA-Z]{2,}
.
) 뒤에 최소 두 글자의 도메인 최상위 레벨(TLD)이 와야 함을 나타냅니다.
useRegularExpression(true)
를 호출하여TextFinder
객체가 정규 표현식을 사용하여 텍스트를 찾도록 설정합니다.findAll()
을 호출하여 정규 표현식에 매칭되는 모든 값을 찾습니다.- 찾은 결과를
forEach()
메소드를 사용하여 반복하고, 각 결과의 행 번호를 로그에 기록합니다.
스크립트를 실행해보겠습니다.
이메일 데이터가 존재하는 모든 행의 위치를 정상적으로 호출하고 있습니다. useRegularExpression()을 사용하면 이메일 주소, 전화번호, 우편번호 등 특정 형식을 갖춘 데이터도 검색이 가능합니다.
이번 포스트에서는 TextFinder 클래스가 제공하는 몇 가지 옵션에 대해서 알아보았습니다. TextFinder 클래스를 활용하면 스프레드시트에서 원하는 텍스트를 빠르게 검색할 수 있습니다. 구글의 공식 레퍼런스를 참조하시려면 아래의 링크를 참조해주세요. 앱스 스크립트를 사용하고 있다면 이 기능들을 사용하고 탐구해보시길 바랍니다!