Abseil Tip 10 문자열 분리, 골치 아프지 않게


title: “이번 주의 팁 #10: 문자열 분리, 골치 아프지 않게!” layout: tips sidenav: side-nav-tips.html published: true permalink: tips/10 type: markdown order: “010” —

원래 2012-08-16에 totw/10으로 게시됨

Greg Miller (jgm@google.com) 작성

2018-01-24 업데이트

내 머릿속에는 이상한 분리가 있다. –John Cleese

문자열을 서브 문자열로 나누는 작업은 모든 범용 프로그래밍 언어에서 흔히 하는 작업이며, C++도 예외는 아닙니다. Google에서 이러한 필요성이 생기자 많은 엔지니어들이 다양한 문자열 분할 함수의 미로 속을 헤매게 되었습니다. 적합한 입력 매개변수, 출력 매개변수 및 동작을 만족하는 마법 같은 조합을 찾기 위해 노력했을 것입니다.

결국, 600줄이 넘는 헤더 파일에 50개 이상의 함수가 정의되어 있는 것을 분석한 끝에, SplitStringViewToDequeOfStringAllowEmpty() 같은 복잡한 이름을 가진 함수를 선택했을지도 모릅니다.

이를 해결하기 위해 C++ 라이브러리 팀은 문자열 분할을 위한 새로운 API를 구현했고, 이는 absl/strings/str_split.h에서 사용할 수 있습니다.

새로운 API는 여러 문자열 분할 함수를 단일 absl::StrSplit() 함수로 대체했습니다. 이 함수는 분할할 문자열과 구분자(delimiter)를 매개변수로 받아들입니다. absl::StrSplit()은 반환 결과를 호출자가 지정한 유형에 적응시킵니다. 내부적으로 absl::string_view를 사용하여 효율적으로 구현되었기 때문에, 호출자가 명시적으로 문자열 객체를 복사해 저장하지 않는 한 추가 복사가 발생하지 않습니다.

말로만 설명하지 말고, 예제를 살펴봅시다:

// 쉼표를 기준으로 분할. string_view의 벡터에 저장(복사 없음).
std::vector<absl::string_view> v = absl::StrSplit("a,b,c", ',');

// 쉼표를 기준으로 분할. 문자열(vector<string>)에 저장(한 번 복사).
std::vector<std::string> v = absl::StrSplit("a,b,c", ',');

// "=>"라는 문자열 기준으로 분할(= 또는 >가 아님).
std::vector<absl::string_view> v = absl::StrSplit("a=>b=>c", "=>");

// ',' 또는 ';'로 분할
using absl::ByAnyChar;
std::vector<std::string> v = absl::StrSplit("a,b;c", ByAnyChar(",;"));

// 다양한 컨테이너에 저장(모두 absl::string_view에서도 작동).
std::set<std::string> s = absl::StrSplit("a,b,c", ',');
std::multiset<std::string> s = absl::StrSplit("a,b,c", ',');
std::list<std::string> li = absl::StrSplit("a,b,c", ',');

// SplitStringViewToDequeOfStringAllowEmpty()와 동일한 동작.
std::deque<std::string> d = absl::StrSplit("a,b,c", ',');

// "a"->"1", "b"->"2", "c"->"3"와 같은 키-값 쌍 반환.
std::map<std::string, std::string> m = absl::StrSplit("a,1,b,2,c,3", ',');

더 자세한 내용은 absl/strings/str_split.h에서 Split API 사용 방법을 확인하고, absl/strings/str_split_test.cc에서 더 많은 예제를 살펴보세요.

읽어주셔서 감사합니다. 이제 정말 “분리”될 시간입니다…