원래 totw/64로 2013-12-09에 게시됨
작성자: Titus Winters (titus@google.com)
2017-10-23 업데이트
빠른 링크: abseil.io/tips/64
"(?:\"(?:\\\\\"|[^\"])*\"|'(?:\\\\'|[^'])*')"; — 고양이가 키보드를 밟고 지나간 흔적일까요, 아니면 여우가 뭐라고 하는 걸까요… 사실, 실제 C++ 코드에서 발견된 지나치게 이스케이프된 정규 표현식입니다.
아마도 C++에서 이스케이프 문제 때문에 정규 표현식을 제대로 이해시키는 데 어려움을 겪은 경험이 있을 것입니다. 마찬가지로, Protobuf나 JSON 데이터를 텍스트 형태로 유닛 테스트에 삽입할 때 따옴표와 줄바꿈을 유지하는 데 짜증이 났을 수도 있습니다. 이스케이프 처리가 많이 필요할수록(심지어 여러 번 중첩된 이스케이프라면 더더욱), 코드의 가독성은 급격히 떨어집니다.
다행히도, C++11에서는 이러한 이스케이프 처리를 제거해 주는 새로운 기능이 추가되었습니다: 바로 raw 문자열 리터럴입니다.
Raw 문자열 리터럴 형식
Raw 문자열 리터럴은 다음과 같은 특별한 문법을 사용합니다:
R"tag(여기에 원하는 내용을 입력하세요)tag"R"tag(여기에 원하는 내용을 입력하세요)tag"tag는 최대 16자의 문자열(빈 태그도 가능합니다)이며, "tag( 이후와 )tag" 사이에 있는 모든 문자는 문자열 리터럴의 내용으로 그대로 사용됩니다. tag에는 괄호, 백슬래시, 공백을 제외한 어떤 문자든 포함될 수 있습니다.
다음의 예를 비교해 보세요:
const char concert_17_raw[] =
"id: 17\n"
"artist: \"Beyonce\"\n"
"date: \"Wed Oct 10 12:39:54 EDT 2012\"\n"
"price_usd: 200\n";const char concert_17_raw[] =
"id: 17\n"
"artist: \"Beyonce\"\n"
"date: \"Wed Oct 10 12:39:54 EDT 2012\"\n"
"price_usd: 200\n";대신에 raw 문자열 리터럴을 사용하면 다음과 같이 작성할 수 있습니다:
const char concert_17_raw[] = R"(
id: 17
artist: "Beyonce"
date: "Wed Oct 10 12:39:54 EDT 2012"
price_usd: 200)";const char concert_17_raw[] = R"(
id: 17
artist: "Beyonce"
date: "Wed Oct 10 12:39:54 EDT 2012"
price_usd: 200)";특별한 경우
들여쓰기 규칙과 raw 문자열 리터럴이 줄바꿈을 포함할 수 있다는 사실을 고려하면, raw 문자열 블록의 첫 번째 줄을 어떻게 들여쓸 것인지에 대해 고민하게 될 수 있습니다. Protobuf 텍스트는 공백을 무시하므로, 선행 줄바꿈을 추가하여(파서에서 무시됨) 문제를 피할 수 있지만, 모든 raw 문자열이 그렇게 관대하지는 않습니다.
문자열 안에 )"가 포함되어 닫는 구분자로 인식되지 않게 하려면, 비어 있지 않은 태그를 사용하는 것이 유용합니다:
std::string my_string = R"foo(This contains quoted parens "()")foo";std::string my_string = R"foo(This contains quoted parens "()")foo";결론
Raw 문자열 리터럴은 대부분의 프로그래머에게 일상적으로 사용하는 도구는 아닙니다. 하지만 이 새로운 언어 기능을 잘 활용하면 가독성을 높일 수 있는 상황이 분명 존재합니다. 다음에 이스케이프를 두 번(\\) 해야 할지 네 번(\\\\) 해야 할지 고민하게 된다면, raw 문자열 리터럴을 대신 사용해 보세요. 독자들이 감사할 것입니다. 물론, 정규 표현식은 여전히 어려울 수 있지만요:
R"regexp((?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'))regexp";R"regexp((?:"(?:\\"|[^"])*"|'(?:\\'|[^'])*'))regexp";reference
https://github.com/abseil/abseil.github.io/blob/master/_posts/2017-10-26-totw-64.md
댓글