String.Format으로 할 수 있는 일들

닷넷 프레임워크를 이용하는 동안, 의외로 곳곳에 훌륭한 기술들이 많이 숨어있습니다. 특히 문자열 처리에 관한 부분은 특별한 경우가 아니면, 기본으로 내장되어있는 API들 (Formatting API와 정규 표현식 API)만으로 쉽게 처리가 가능합니다. 예전 블로그 아티클 중에 정규표현식에 관련된 아티클들이 몇 가지 있으니 이 아티클과 더불어서 보시면 좋을것 같습니다.


 


오늘 살펴보려고 하는 내용은 String Formatting API에 대한 내용입니다.


 


1. 자유자재로 사용하는 치환자


 


대부분의 예제, 대부분의 코드에서는 String Formatting API에 서식 문자열을 지정할 때, 인자 순서대로, 단 한 번씩만 치환자를 사용합니다. 하지만, 같은 치환자를 여러번 중복해서 사용하거나, 인자 순서와는 별개로 지정할 필요는 많습니다. 이럴 때에는, 걱정하지 말고 매개 변수 개수에 유의하면서 치환자를 자유롭게 사용하면 됩니다.


 

String.Format(“{0} {1} {1} {4} {3} {2}”, ‘a’, ‘b’, ‘c’, ‘d’, ‘e’);
// => a b b e d c

 


2. C# 만의 편리한 기능: Verbatim String과 함께 사용하는 강력한 Formatting API


 


여러 줄에 걸친 문자열을 별도의 데이터 파일이 아닌, C# 코드 내에 포함할 수 있다면, 좀 더 String Formatting API를 극적으로 활용할 수 있을 것입니다. 이럴 때, Verbatim String을 활용하면 좋습니다. Verbatim String은 @” 으로 시작하여 ” 로 끝이나는 문자열 구문 전체를 말합니다. 이 문자열 블럭 안에는 Back Slash나 CR/LF 등의 문자를 포함할 수 있습니다.


 

String.Format(@”<html>
<head><title>Hello World!</title></head>
<body>
<p>{0}</p>
</body>
</html>”, DateTime.Now);

 


다만 유의할 점이 하나 있다면, 문자열이 파일로부터 나타난 것이든, Verbatim String에 의한 것이든, 의미를 다르게 해석할 가능성이 있는 글자 (예: ‘{‘ 나 ‘}’ 같은 글자)들은 그 의미를 정확하게 살릴 수 있도록 지정하거나, 같은 문자를 연속으로 두번으로 지정하여 이스케이프 처리해야 합니다. (예: “{{“, “}}”)


 

String.Format(@”int main(int argc, char **argv) {
return 0;
}”);

 


즉, 위의 경우 String.Format 메서드에서 오류를 반환합니다. 치환자 시작 기호 다음에 적절한 수식 대신 다른 문자열들이 열거되기 때문에 치환할 수 없다는 오류가 발생합니다. 위의 경우 중괄호 부분들을 아래와 같이 수정해야 합니다.


 

String.Format(@”int main(int argc, char **argv) {{
return 0;
}}”);

 


위의 예시에서는 C 언어 코드에 대한 것을 예로 들었습니다만, 같은 방법으로 C# 프로그래밍 코드를 코드 안에 포함하여 재사용할 수도 있습니다. 또는, IronPython 등의 코드를 Embedding하여 DLR에서 사용할 수 있도록 재구성하는 시나리오도 생각해 볼 수 있을 것입니다.


 


3. 날짜 및 시간 표현을 자유자재로 활용하기


 


아직도 날짜 및 시간 표현을 위하여 문자열을 조립하거나, 알고리즘을 사용하여 오전/오후를 구분하십니까? 그렇게 할 이유가 없습니다. 오히려 좀 더 세밀하고 다양한 기능을 제공하는 기본 기능이 있기 때문입니다.


 

String.Format(@”{0:yyyy-MM-dd}”, DateTime.Now); // 2009-01-30
String.Format(@”{0:tt hh:mm:ss}”, DateTime.Now); // 오전 01:47:33
String.Format(@”{0:yyyy-MM-dd tt hh:mm:ss}”, DateTime.Now); // 2009-01-30 오전 01:48:11

 


만약 오전/오후에 해당하는 문자열을 한글이 아닌 영문 표기 (AM/PM)로 변경하려면 어떻게 해야 할까요? 이럴 때에는 CultureInfo 객체를 Format 메서드에 전달하면 간단해집니다. CultureInfo는 System.Globalization 네임스페이스 안에 있습니다.


 

String.Format(CultureInfo.GetCultureInfo(“en-US”), @”{0:tt hh:mm:ss}”, DateTime.Now); // AM 04:30:44
String.Format(CultureInfo.GetCultureInfo(“ko-KR”), @”{0:tt hh:mm:ss}”, DateTime.Now); // 오후 03:03:02
String.Format(CultureInfo.GetCultureInfo(“ja-JP”), @”{0:tt hh:mm:ss}”, DateTime.Now); // 午後 10:08:03

 


위의 예시에서 주석으로 표시한 것과 같이 현재 시간에서 “오전”과 “오후”에 대한 표현을 해당 국가의 언어의 표기법에 맞추어 표기하고 있습니다. en-US는 언어를 영어로 사용하며 지리적으로 미국을 기준으로 한다는 의미로 해석되며, ko-KR은 언어를 한국어로 사용하고 지리적으로는 대한민국, ja-JP는 언어를 일본어로 사용하고 지리적으로 일본을 기준으로 한다는 의미로 해석됩니다.


 


위와 같이 언어 및 지역 코드를 설정할 때 알아야 할 사항이 두 가지가 있는데, 첫 째는 반드시 언어 코드의 전체 이름을 기재해야 합니다. 예를 들어, en-US에서 en만 지정하면 en에 해당하는 설정은 “중립 문화권”이기 때문에 CultureInfo.GetCultureInfo 메서드로는 받아들일 수 없습니다. 그리고 US만 지정하면 US에 해당하는 코드가 없으므로 역시 오류가 발생합니다. 그리고, 언어 코드가 시간대 설정까지 자동으로 반영하는 것은 아니므로 en-JP (언어는 영어이며 지역은 일본)와 같은 설정은 유효하지 않으며 표준 코드 정의 내역에 없기 때문에 받아들여지지 않습니다. 시간대에 대한 설정은 http://msdn.microsoft.com/ko-kr/library/system.timezone.aspx 에 소개된 TimeZone 클래스 (닷넷 3.5부터 사용 가능합니다)를 활용해야 합니다.


 


4. 통화 금액 표현하기


 


지역 설정을 이용하여 손쉽게 처리할 수 있는 일이 또 한 가지 있는데, 바로 통화 금액 표기에 관한 것입니다. 아래의 코드를 살펴보기로 하겠습니다.


 

String.Format(CultureInfo.GetCultureInfo(“es-ES”), “{0:C}”, 300); // 300,00 €
String.Format(CultureInfo.GetCultureInfo(“ko-KR”), “{0:C}”, 300); // ₩300

 


그리고, 좀 더 구체적으로 소수점 자릿수 등을 표현하거나, 음수/양수/영점 표현을 설정하고자 한다면 아래와 같이 활용할 수 있습니다. (Delphi Basic 웹 사이트 http://www.delphibasics.co.uk/RTL.asp?Name=FormatFloat 에서 부분 발췌한 샘플 코드를 올립니다.)


 

// 반올림 예시
String.Format(“{0:#####}”, 1234.567);
String.Format(“{0:00000}”, 1234.567);
String.Format(“{0:0}”, 1234.567);
String.Format(“{0:#,##0}”, 1234.567);
String.Format(“{0:0,0}”, 1234.567);

// 소수점 사용 예시
String.Format(“{0:0.####}”, 1234.567);
String.Format(“{0:0.0000}”, 1234.567);

// 공학용 표기
String.Format(“{0:0.0000000E+00}”, 1234.567);
String.Format(“{0:0.0000000E-00}”, 1234.567);
String.Format(“{0:#.#######E-0#}”, 1234.567);

// 음수/양수/ZERO 에 따른 표기
String.Format(“{0:0.0}”, -1234.567);
String.Format(“{0:0.0 CR;0.0 DB}”, -1234.567);
String.Format(“{0:0.0 CR;0.0 DB}”, 1234.567);
String.Format(“{0:0.0 CR;0.0 DB;Zero}”, 0.00);


5. Bonus: 자연스러운 16진수 표기 방법 (String.Format을 사용하지 않습니다.)


 

“0x” + (16).ToString(“X8”); // 8자리 16진수 표기, 대문자
“0x” + (33).ToString(“x4”); // 4자리 16진수 표기, 소문자

 

댓글 남기기