23. Text Manipulation

23.1. Text

프로그래머들은 텍스트들을 많이 다룬다.

23.2. Strings

C++에서는 문자열을 std::string으로 제공한다. 실제로는 std::basic_string<char>의 템플릿 클래스이다. 다른 오브젝트를 std::string으로 만들고 싶으면 std::to_string을 쓰면 된다.

from_string도 비슷하게 만들 수 있다.

template<typename T>
T from_string(const std::string& s)
 {
          std::istringstream is {s};
          T t;
          if (!(is >> t)) throw std::bad_cast("");
          return t;
}

이를 이용해 다른 타입의 오브젝트간 컨버전도 할 수 있다.

template<typename Target, typename Source>
Target to(Source arg)
{
          std::stringstream interpreter;
          Target result;

          if (!(interpreter << arg)                                       // write arg into stream
                    || !(interpreter >> result)                          // read result from stream
                    || !(interpreter >> std::ws).eof())           // stuff left in stream?
                              throw std::runtime_error{"to<>() failed"};

          return result;
}

23.3. I/O streams

입출력 스트림은 입출력뿐만 아니라 문자열로부터의/로의 변환도 수행한다.

23.4. Maps

std::map 등 연관 컨테이너는 문자열을 다루는 데 있어서 핵심이다. std::multimap은 중복을 허용한다. std::unordered_map, std::unordered_multimap은 비순차 컨테이너이다.

23.4.1. Implementation details

메일 프로세서를 구현해 보자.

23.5. A problem

정규 표현식을 쓸 수는 없을까?

23.6. The idea of regular expressions

C++에서도 정규 표현식을 지원한다.

23.6.1. Raw string literals

문자열 리터럴에서 이스케이프 문자는 \\로 넣어줘야 한다. 아니면 R을 앞에 붙여줄 수도 있다.

23.7. Searching with regular expressions

std::regex을 이용해 우편 번호 패턴을 매칭해 보자.

          std::ifstream in {"file.txt"};                                         // input file
          if (!in) std::cerr << "no file\n";

          std::regex pat {R"(\w{2}\s*\d{5}(–\d{4})?)"};           // postal code pattern

          int lineno = 0;
          for (std::string line; std::getline(in,line); ) {     // read input line into input buffer
                    ++lineno;
                    std::smatch matches;                         // matched strings go here
                    if (std::regex_search(line, matches, pat))
                              std::cout << lineno << ": " << matches[0] << '\n';
          }

23.8. Regular expression syntax

여러 다른 정규표현식이 있다.

23.8.1. Characters and special characters

정규표현식에서는 특수한 문자들이 존재한다. 그룹핑 문자인 () 등.

23.8.2. Character classes

\d, \l 등 문자 클래스들을 위한 기호도 존재한다.

23.8.3. Repeats

반복되는 문자들은 숫자로 표기한다.

23.8.4. Grouping

패턴을 그룹핑할 수 있다.

23.8.5. Alternation

| 로 대안 패턴을 매칭할 수 있다.

23.8.6. Character sets and ranges

[a-zA-Z] 등으로 커스텀 문자 셋을 정의할 수 있다. [^a-zA-Z]의 ^는 해당 커스텀 문자 셋을 제외하라는 뜻이다.

23.8.7. Regular expression errors

올바르지 못한 정규 표현식은 std::bad_expression 예외로 잡힌다.

23.9. Matching with regular expressions

정규 표현식은 매칭에 유용하다. 기능적으로 편리한 것이지 쓰기 쉬운 것은 아니므로 구현에 주의하라.

23.10. References

더 많은 정보를 얻고 싶다면:

https://en.cppreference.com/w/cpp/regex

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Google photo

Google의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 /  변경 )

%s에 연결하는 중