티스토리 뷰

반응형

 

# 용어 정리

String literals - 소스의 문자 시퀀스(sequence of characters)  

String delimiters - 문자 시퀀스(sequence of characters)의 시작과 끝에서 경계를 설정. Swift의 string delimiter는 "(큰따옴표) 

Escape characters - String literals내에서 하나 이상의 후속 Character를 특별하게 해석한다. Swift의 Escape character는 \(백슬래시) 

Escape character sequences(== Escape sequence) - 특수한 문자를 나타내며, Escape characters(\)로 시작하게 된다. 

 

Escape sequence는 다음과 같은것들이 있다. 

1. String interpolation(문자열 보간)

let name = "정대만"
let str = "불꽃남자 \(name)"

2. Escaped special characters

\0 (null character), 
\\ (backslash), 
\t(horizontal tab), 
\n (line feed), 
\r (carriage return), 
\" (double quotation mark) 
\' (single quotation mark)

3. 유니코드 스칼라 나타내기 

let sparklingHeart = "\u{1F496}" // 💖

 

# Escaped special characters

위 escape sequence중 2번인 Escaped special characters를 사용할 때를 보자. 

let str = "정대만\t"

\t는 horizontal tab을 의미하기 때문에 컴파일러가 아 ㅇㅋ 하면서 컴파일에러가 나지 않지만..

let str = "정대만\e" // ⛔️ Invalid escape sequence in literal

Swift에서는 반드시 이 escaped special characters가 유효한 것이어야 하는데, \e같은것들은 유효하지 않기 때문에 에러가 발생하는 것이다.

이러한 String literal에서 굳이 \(백슬래시)를 사용하여 문자를 나타내고 싶다면, 또 다른 \(백슬래시)로 escape해야한다. (\\)

let str = "정대만\\e" // ✅

Invalid escape sequence in literal 에러는 Multiline String Literals에서도 동일하게 발생한다. 

let str = """
            	정대만\e // ⛔️ Invalid escape sequence in literal
          """

 


# Raw string literals

Raw string literals은 escape sequence를 무시한다. 

즉, 위에서 우리가 봤던

1. String interpolation(문자열 보간)

2. Escaped special characters

3. 유니코드 스칼라 나타내기 

는 Raw string literals에서는 무시되고 "Raw(원시)" Text로 나타낼 수 있게 된다. 

Swift 5.0에서 이를 가능하게 하는 Extended String Delimiters 라는 것이 나왔다.

 

Extended String Delimiters #".."#

Extended String Delimiters를 사용하면 raw string literal를 나타낼 수 있게 된다. 

#"String literal"# 로 표현할 수 있다. 원래 "(큰따옴표)로 감싸줘야하니 양 끝에 #을 붙힌다고 생각하면 된다. 

1. String interpolation(문자열 보간)

let name = "정대만"
let str = #"불꽃남자 \(name)"# // 불꽃남자 \(name)

불꽃남자 정대만이 나오지 않고 \(name) 그 자체가 나오게 된다.

 

2. Escaped special characters

let str = #"서태웅\n서태웅\e"# // 서태웅\n서태웅\e

\n이 escaped special characters임에도 불구하고 \n그대로 나온것을 볼 수 있다.

 

3. 유니코드 스칼라 나타내기 

let sparklingHeart = #"\u{1F496}"# // \u{1F496}

💖로 나오지 않고 \u{1F496}문자 그자체가 나온것을 볼 수 있다.

 

문자열을 감싸는 #의 개수는 상관없다. 앞뒤 #의 개수가 맞기만 하면 된다.

let str = ####"서태웅\n서태웅\e"#### // 서태웅\n서태웅\e

Extended String Delimiters + Multiline String Literals조합도 당연히 가능하다.

let str = #"""
서태웅
\n
서태웅
\e
"""#
// 서태웅
// \n
// 서태웅
// \e

 

그렇다면 Extended String Delimiters를 사용하면 무조건 escape sequence는 무시되는 것일까? 

아니다. 요것도 필요하다면 할 수 있는데, \(백슬래시) 다음에 #를 붙혀주는 것이다.

 

1. String interpolation(문자열 보간)

let name = "정대만"
let str = #"불꽃남자 \#(name)"# // 불꽃남자 정대만

2. Escaped special characters

let str = #"서태웅\#n서태웅\e"#
// 서태웅
// 서태웅\e

3. 유니코드 스칼라 나타내기 

let sparklingHeart = #"\#u{1F496}"# // 💖

 

이때 주의해야할 사항이 있는데, \(백슬래시)뒤에 붙는 #의 개수가 문자열을 감싼 #의 개수가 맞아야 한다는 것이다.

let str = ##"서태웅\#n서태웅\e"## 
// 서태웅\#n서태웅\e 

let str = ##"서태웅\##n서태웅\e"##
// 서태웅
// 서태웅\e

첫번째 str은 2개의 #으로 감싸져있지만 \#n으로 나타냈기 때문에 Escaped special characters가 무시되고 그냥 \#n문자 그 자체가 나온것을 볼 수 있다.

#을 몇개를 붙히든 상관없다. 문자열을 감싼 #과 \뒤에 붙는 #의 개수가 맞기만 하면된다.

Extended String Delimiters + Multiline String Literals 조합에서도 적용되는 규칙이다. 

let str = ##"""
서태웅\##n
서태웅
\e
"""##
// 서태웅
// 
// 서태웅
// \e

문자열을 감싼 #가 2개니, \n을 문자열 그대로가 아닌 escaped special characters로서 나타내고 싶다면 \##n으로 표시해줘야하는 것. 

 

Extended String Delimiters는 정규식에서 굉장히 유용한 기능인데, 예를 들어 정규식에서는 \d는 [0-9]를 나타낸다. 

하지만 Swift에서는 \d는 유효하지 않은 escaped character이기 때문에 한번더 escape하여 \\d로 표현해줘야한다. 

func isValid(_ digits: String) -> Bool {

    let pattern = "\\d" // "\d"로 할 경우 컴파일에러
    let range = digits.range(of: pattern, options: .regularExpression)
    return range != nil
}

짧은 정규식은 괜찮을지 몰라도, 계속 \\를 붙혀주다보면 가독성도 떨어지기 마련인데 Extended String Delimiters를 사용하면 \d로만 적어줘도 되는 것이다. (== \(백슬래시)를 한번만 적어줘도 되는것이다.)

func isValid(_ digits: String) -> Bool {

    let pattern = #"\d"# 
    let range = digits.range(of: pattern, options: .regularExpression)
    return range != nil
}

Regex 공부하다가 요거 먼저 정리해두면 좋을 것 같아서.. 틀린부분이 있다면 댓글 달아주세요.

애매하게 알던 지식이었는데, 이번기회에 확실하게 알게 된 것 같아서 좋네요!

예제는 아 얘 슬램덩크 진짜 재밌게 봤나보다...하고 넘어가주세여ㅛ

슬램덩크라는거 정말 아름다운거였구나

 

[참고]

https://docs.swift.org/swift-book/LanguageGuide/StringsAndCharacters.html

https://github.com/apple/swift-evolution/blob/main/proposals/0200-raw-string-escaping.m

반응형