자바 split 메소드로는 .
을 이용해 문자열을 분리할 수 없다. "12.345-6.A".split(".")
의 호출 결과는 [12, 345-6, A]
가 아니다. 빈 배열을 반환한다. split의 구분 문자열은 실제로는 정규식(regular expression)이기 때문이다. 따라서 .
는 모든 문자를 나타내는 정규식으로 해석된다.
코틀린에서는 자바의 split 대신에 여러 가지 다른 조합의 파라미터를 받는 split 확장 함수를 제공함으로써 혼동을 야기하는 메소드를 감춘다. 정규식을 파라미터로 받는 함수는 String이 아닌 Regex 타입의 값을 받는다. 따라서 코틀린에서는 split 함수에 전달하는 값의 타입에 따라 정규식이나 일반 텍스트 중 어느 것으로 문자열을 분리하는지 쉽게 알 수 있다.
정규식을 사용하지 않고 파싱하기
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: $extension")
}
fun main(args: Array<String>) {
val path = "/Users/yole/kotlin-book/chapter.adoc"
parsePath(path)
}
// 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")
}
}
여러 줄 문자열을 코드에서 더 보기 좋게 표현하고 싶다면 들여쓰기를 하되 들여쓰기의 끝부분을 특별한 문자열로 표시하고, trimMargin을 사용해 그 문자열과 그 직전의 공백을 제거한다.
fun main(args: Array<String>) {
val kotlinLogo = """| //
.| //
.|/ \\""".trimMargin(".")
println(kotlinLogo)
}
/*
| //
| //
|/ \\
*/