서론
오늘 코딩 테스트 연습을 하던 중 반복문이 아닌 정규식을 사용할 때 효율이 더 좋은 경우가 있어서 정규 표현식에 대해 정리해보려고 한다.
정규 표현식
- 정규 표현식 또는 정규식은 특정한 규칙을 가진 문자열의 집합을 표현하기 위해 사용하는 형식 언어이다.
- 정규 표현식(Regular Expression, 줄여서 Regex)은 문자열에서 특정 패턴을 찾거나, 추출하거나, 교체하는 데 사용되는 강력한 도구이다.
kotlin에서는 정규 표현식을 쉽게 다룰 수 있는 다양한 기능을 제공한다.
정규 표현식 문법
- ^ : 문자열의 시작을 의미
- $ : 문자열의 끝을 의미
- . : 문자 한 개를 의미. '.'이 위치한 곳에 어떤 문자든지 1개의 문자가 들어감
- [ ] : 대괄호에 있는 문자 중 한 개를 의미. [abc]는 a, b, c 중 하나를 선택
- [^] : not의 의미로, 대괄호에서 쓴다면 [^abc] : a, b, c 제외하고 나머지를 의미.
- | : or을 의미. a|b : a 또는 b.
- () : 공통되는 부분을 묶을 때, 서브 패턴을 지정할 때 사용. abc|abd -> ab(c|d)로 바꿀 수 있음.
- ? : 문자가 0회 또는 1회 등장. a? b는 a가 나올 수도, 없을 수도 있음. ab, b.
- * : 문자가 0회 이상 등장. a*b : b, ab, aaab, aaab..
- + : 문자가 1회 이상 등장. a+b : ab, aab, aaab..
- {n} : 문자가 n개 나옴. a {2} b : aab
- {n,} : 문자가 n개 이상 나옴. a {2,} b : aab, aaab, aaaab..
- {n, m} : 문자가 n개 이상 m개 이하로 나옴. a {1,3 } b : ab, aab, aaab
- \s : 공백 제거
- \t : 탭
- \d : 숫자, [0-9]와 동일
- \b : 단어의 경계, 문자 사이의 공백
- \w : 알파벳이나 숫자, [a-zA-Z0-9_]와 동일
위의 \s, \t, \d, \b, \w는 대문자로 바꾸면 반대 의미
sample code
정규 표현식 객체 생성 - kotlin에서는 "Regex" 클래스를 사용하여 정규 표현식을 생성한다.
val regex = Regex("pattern")
val regex2 = "pattern".toRegex()
문자열 매칭
정규식의 가장 기본적인 기능은 문자열이 패턴과 일치하는지 확인하는 것이다. 아래는 "matches" 함수를 사용한 예시입니다.
val regex = Regex("[a-z]+")
val input = "hello"
val isMatch = regex.matches(input)
println(isMatch) // true
소문자 알파벳이 하나 이상 있는지 체크하는 예제로 true를 반환한다.
부분 문자열 매칭
문자열의 일부분이 정규 표현식과 일치하는지 확인하려면 "containsMatchIn" 함수를 사용한다.
val regex = Regex("[0-9]+")
val input = "Kotlin123"
val containsMatch = regex.containsMatchIn(input)
println(containsMatch) // true
숫자가 하나 이상 있는지를 확인하는 코드로, true를 반환한다.
매칭된 부분 추출
정규식에 매칭된 부분을 추출하려면 "find" 함수를 사용한다. 이 함수는 첫 번째 매칭 결과를 반환한다.
val regex = Regex("[0-9]+")
val input = "Kotlin123"
val matchResult = regex.find(input)
println(matchResult?.value) // 123
여러 매칭 결과를 모두 추출하려면 "findAll" 함수를 사용한다.
val regex = Regex("[0-9]+")
val input = "Kotlin123 and 456"
val matchResults = regex.findAll(input)
for (match in matchResults) {
println(match.value) // 123 456
}
문자열 교체
정규식을 사용하여 문자열의 일부분을 다른 문자열로 교체하려면 "replace" 함수를 사용한다.
val regex = Regex("[0-9]+")
val input = "Kotlin123 and 456"
val replaced = regex.replace(input, "#")
println(replaced) // Kotlin# and #
패턴에 매칭되는 모든 부분을 교체하려면 replace 대신 replaceAll 함수를 사용한다.
val replacedAll = input.replace(regex, "#")
println(replacedAll) // Kotlin# and #
고급 정규식
정규식에서는 다양한 고급 기능을 사용할 수 있다. 예를 들면, 그룹화, 선택, 반복 등을 활용하여 더 복잡한 패턴을 만들 수 있다.
val regex = Regex("(\\d{3})-(\\d{2})-(\\d{4})")
val input = "123-45-6789"
val matchResult = regex.find(input)
if (matchResult != null) {
println(matchResult.value) // 123-45-6789
println(matchResult.groupValues) // [123-45-6789, 123, 45, 6789]
}
위의 예제에서 (\\d{3})-(\\d{2})-(\\d{4}) 정규 표현식은 미국 사회보장번호(SSN) 형식을 매칭한다. 그룹화 기능을 사용하여 각 부분(123, 45, 6789)을 별도로 추출할 수 있습니다.
마치며
Kotlin에서 정규 표현식을 사용하는 방법을 정리해보았습니다. 기본적인 사용법을 이해하고, 복잡한 정규식에 대한 연습을 한 뒤 실제 프로젝트 및 코딩 테스트에서 정규식을 활용한다면 보다 효율적인 작업이 가능할 것 같다고 느꼈습니다😊