마침표(.)는 모든 문자를 나타내는 정규식으로 해석된다.
코틀린에서는 split 함수에 전달하는 값의 타입에 따라 정규식이나 일반 텍스트 중 어느 것으로 문자열을 분리하는지 쉽게 알 수 있다.
다음 코드는 마침표나 대시(-)로 문자열을 분리하는 예를 보여준다.
-> println("12.345-6.A".split("\\.|-".toRegex())) // 정규식을 명시적으로 만든다.
[12, 345, 6, A]
코틀린에서는 toRegex 확장 함수를 사용해 문자열을 정규식으로 변환할 수 있다.
위 코드처럼 간단한 경우에는 꼭 정규식을 쓸 필요도 없다.
split 확장 함수를 오버로딩한 버전 중에는 구분 문자열을 하나 이상 인자로 받는 함수가 있다.
-> println("12.345-6.A".split(".","-"))
[12, 345, 6, A]
이렇게 여러 문자를 받을 수 있는 코틀린 확장 함수는 자바에 있는 단 하나의 문자만 받을 수 있는 메서드를 대신한다.
String 확장 함수를 사용해 경로를 파싱해보자.
fun parsePath(path: String) {
val directory = path.substringBeforeLast("/")
val fullName = path.substringAfterLast("/")
val fileName = fullName.substringBeforeLast(".")
val extension = fullName.substringAfterLast(".")
println("Dir: $directory, name: $fileName, ext: $extention")
}
-> parsePath("/Users/yole/kotlin-book/chapter.adoc")
Dir: /Users/yole/kotlin-book, name: chapter, ext: adoc
정규식이 필요할 때는 코틀린 라이브러리를 사용하면 더 편하다.
다음은 같은 작업을 정규식을 활용해 구현한 프로그램이다.
fun parsePath(path: String) {
val regex = """(.+)/(.+)\.(.+)""".toRegex()
val matchResult = regex.matchEntire(path)
if (matchResult != null) {
val (directory, filename, extension) = matchResult.destructured
println("Dir: $directory, name: $filename, ext: $extension")
}
}
위 예제에서는 3중 따옴표 문자열을 사용해 정규식을 썼다.
3중 따옴표 문자열에서는 역슬래시()를 포함한 어떤 문자도 이스케이프할 필요가 없다.
예를 들어 일반 문자열을 사용해 정규식을 작성하는 경우 마침표 기호를 이스케이프 하려면 (역슬래시)(역슬래시). 라고 써야 하지만, 3중 따옴표 문자열에서는 (역슬래시). 라고 쓰면 된다.
매치에 성공하면 그룹별로 분해한 매치 결과를 의미하는 destructured 프로퍼티를 각 변수에 대입한다.
3중 따옴표 문자열을 문자열 이스케이프를 피하기 위해서만 사용하지는 않는다.
3중 따옴표 문자열에는 줄 바꿈을 표현하는 아무 문자열이나 (이스케이프 없이) 그대로 들어간다.
아래 코드는 아스키코드로 글자만 사용해 그린 그림을 하나 출력한다.
val kotlinLogo = """| //
.| //
.|/ \"""
println(kotlinLogo.trimMargin("."))
| //
| //
|/ \
여러 줄 문자열을 코드에서 더 보기 좋게 표현하고 싶다면 들여쓰기를 하되 들여쓰기의 끝부분을 특별한 문자열로 표시하고, trimMargin을 사용해 그 문자열과 그 직전의 공백을 제거한다.
(위 코드에서는 .을 사용해 들여쓰기 한 부분을 표시하고, trimMargin(".") 메서드를 통해 .과 직전의 공백을 모두 제거했다.)
경로를 일반 문자열로 표현한다면
"C:\Users\yole\kotlin-book" 이지만 (\가 실제로 2개 들어감. 이스케이프 문자 규칙을 따르기 때문에)
경로를 3중 따옴표 문자열로 쓰면
"""C:\Users\yole\kotlin-book""" 이다.
참고로 3중 따옴표 문자열 안에서는 이스케이프가 불가능하다.
그러나 만약 문자열 템플릿의 시작을 의미하는 $를 3중 따옴표 문자열 안에 넣어야 한다면
val price ="""{''}99.9""" 처럼 문자열 템플릿 안에 '$' 문자를 넣어서 써야한다.
3중 따옴표 문자열은 복잡하게 이스케이프를 쓰거나 외부 파일에서 텍스트를 불러올 필요가 없으므로 매우 유용한 기능이다.