🔍 Reguläre Ausdrücke
📖 Was sind reguläre Ausdrücke?
Reguläre Ausdrücke (Regular Expression, Regex) sind eine Methode zum Ausdrücken von Zeichenkettenmustern. Sie werden für Suche, Validierung, Extraktion, Ersetzung und mehr verwendet!
💡 Grundlegende Verwendung
Regex erstellen
fun main() {
// Regex-Objekt erstellen
val regex1 = Regex("hello")
val regex2 = "hello".toRegex()
// Abgleich überprüfen
println(regex1.matches("hello")) // true
println(regex1.matches("Hello")) // false (Groß-/Kleinschreibung beachtet)
}
Einfacher Abgleich
fun main() {
val text = "My email is hong@example.com"
// contains
val hasEmail = Regex("@").containsMatchIn(text)
println(hasEmail) // true
// find
val match = Regex("\\w+@\\w+\\.\\w+").find(text)
println(match?.value) // hong@example.com
}
🎯 Grundlegende Muster
Zeichenklassen
fun main() {
// \d - Ziffer
println("123".matches(Regex("\\d+"))) // true
// \w - Wortzeichen (Buchstaben, Ziffern, _)
println("hello_123".matches(Regex("\\w+"))) // true
// \s - Leerzeichen
println(" ".matches(Regex("\\s"))) // true
// . - Beliebiges Zeichen
println("abc".matches(Regex("..."))) // true (3 Zeichen)
}
Quantoren
fun main() {
// + : 1 oder mehr
println("aaa".matches(Regex("a+"))) // true
// * : 0 oder mehr
println("".matches(Regex("a*"))) // true
// ? : 0 oder 1
println("a".matches(Regex("a?"))) // true
// {n} : Genau n
println("aaa".matches(Regex("a{3}"))) // true
// {n,m} : Zwischen n und m
println("aaa".matches(Regex("a{2,4}"))) // true
}
🎨 Praxisbeispiele
E-Mail-Validierung
fun isValidEmail(email: String): Boolean {
val pattern = "[a-zA-Z0-9._-]+@[a-z]+\\.+[a-z]+"
return email.matches(pattern.toRegex())
}
fun main() {
println(isValidEmail("hong@example.com")) // true
println(isValidEmail("invalid.email")) // false
println(isValidEmail("test@domain.co.kr")) // true
}
Telefonnummer-Validierung
fun isValidPhone(phone: String): Boolean {
// 010-1234-5678 oder 01012345678
val pattern = "010-?\\d{4}-?\\d{4}"
return phone.matches(pattern.toRegex())
}
fun main() {
println(isValidPhone("010-1234-5678")) // true
println(isValidPhone("01012345678")) // true
println(isValidPhone("02-1234-5678")) // false
}
Passwortstärke
fun checkPasswordStrength(password: String): String {
val hasLength = password.length >= 8
val hasDigit = Regex("\\d").containsMatchIn(password)
val hasLower = Regex("[a-z]").containsMatchIn(password)
val hasUpper = Regex("[A-Z]").containsMatchIn(password)
val hasSpecial = Regex("[!@#$%^&*]").containsMatchIn(password)
return when {
hasLength && hasDigit && hasLower && hasUpper && hasSpecial -> "Sehr stark"
hasLength && hasDigit && (hasLower || hasUpper) -> "Stark"
hasLength -> "Mittel"
else -> "Schwach"
}
}
fun main() {
println(checkPasswordStrength("Pass123!")) // Sehr stark
println(checkPasswordStrength("password123")) // Stark
println(checkPasswordStrength("password")) // Mittel
println(checkPasswordStrength("pass")) // Schwach
}
URL-Extraktion
fun extractUrls(text: String): List<String> {
val pattern = "https?://[\\w./]+"
return Regex(pattern).findAll(text).map { it.value }.toList()
}
fun main() {
val text = """
Visit https://kotlin.org for info.
Check http://example.com too!
""".trimIndent()
val urls = extractUrls(text)
urls.forEach { println(it) }
// https://kotlin.org
// http://example.com
}
Hashtag-Extraktion
fun extractHashtags(text: String): List<String> {
val pattern = "#\\w+"
return Regex(pattern).findAll(text).map { it.value }.toList()
}
fun main() {
val tweet = "Das Wetter ist heute schön #Wetter #Glück #Kotlin"
val hashtags = extractHashtags(tweet)
println("Hashtags:")
hashtags.forEach { println(it) }
// #Wetter
// #Glück
// #Kotlin
}
🔧 Erweiterte Funktionen
Gruppenerfassung
fun parseDate(text: String): Triple<String, String, String>? {
val pattern = "(\\d{4})-(\\d{2})-(\\d{2})"
val match = Regex(pattern).find(text) ?: return null
val (year, month, day) = match.destructured
return Triple(year, month, day)
}
fun main() {
val date = parseDate("Today is 2024-12-25")
if (date != null) {
val (year, month, day) = date
println("Year: $year, Month: $month, Day: $day")
}
}
Ersetzung
fun main() {
val text = "My phone is 010-1234-5678"
// Telefonnummer maskieren
val masked = text.replace(Regex("\\d{4}$"), "****")
println(masked) // My phone is 010-1234-****
// Mehrere Leerzeichen zu einem
val multiSpace = "Hello World !"
val cleaned = multiSpace.replace(Regex("\\s+"), " ")
println(cleaned) // Hello World !
}
Aufteilung
fun main() {
// Mit Komma oder Leerzeichen trennen
val text = "apple, banana orange,grape"
val fruits = text.split(Regex("[,\\s]+"))
println(fruits) // [apple, banana, orange, grape]
// Mit Ziffern trennen
val text2 = "item1,item2,item3"
val items = text2.split(Regex("\\d+"))
println(items) // [item, ,item, ,item, ]
}
🎯 Praktische Muster
HTML-Tags entfernen
fun removeHtmlTags(html: String): String {
return html.replace(Regex("<[^>]*>"), "")
}
fun main() {
val html = "<p>Hello <b>World</b>!</p>"
val text = removeHtmlTags(html)
println(text) // Hello World!
}
Zahlen extrahieren
fun extractNumbers(text: String): List<Int> {
return Regex("\\d+").findAll(text)
.map { it.value.toInt() }
.toList()
}
fun main() {
val text = "I have 3 apples and 5 oranges"
val numbers = extractNumbers(text)
println(numbers) // [3, 5]
}
Währungsformatierung
fun formatCurrency(amount: Int): String {
return amount.toString().replace(Regex("(\\d)(?=(\\d{3})+$)"), "$1,")
}
fun main() {
println(formatCurrency(1000)) // 1,000
println(formatCurrency(1234567)) // 1,234,567
}
🤔 Häufig gestellte Fragen
F1. Groß-/Kleinschreibung ignorieren?
A: Verwenden Sie RegexOption!
fun main() {
val regex = Regex("hello", RegexOption.IGNORE_CASE)
println(regex.matches("Hello")) // true
println(regex.matches("HELLO")) // true
println(regex.matches("hello")) // true
}
F2. Escaping?
A: Zwei Backslashes!
fun main() {
// . als Literal abgleichen
val dotRegex = Regex("\\.")
println("3.14".contains(dotRegex)) // true
// ( ) als Literal
val parens = Regex("\\(.*\\)")
println("(test)".matches(parens)) // true
}
F3. Leistung?
A: Kompilierte Regex wiederverwenden!
// ❌ Jedes Mal kompilieren
fun bad(text: String): Boolean {
return text.matches(Regex("\\d+")) // Langsam
}
// ✅ Nur einmal kompilieren
val NUMBER_REGEX = Regex("\\d+")
fun good(text: String): Boolean {
return text.matches(NUMBER_REGEX) // Schnell
}
📚 Übersicht wichtiger Muster
Zeichen:
^ - Anfang
$ - Ende
. - Beliebiges Zeichen
\d - Ziffer [0-9]
\D - Keine Ziffer
\w - Wortzeichen [a-zA-Z0-9_]
\W - Kein Wortzeichen
\s - Leerzeichen
\S - Kein Leerzeichen
Quantoren:
* - 0 oder mehr
+ - 1 oder mehr
? - 0 oder 1
{n} - Genau n
{n,} - n oder mehr
{n,m} - Zwischen n und m
Gruppen:
(...) - Gruppe
| - ODER
[abc] - Eins von a, b, c
[^abc] - Nicht a, b, c
[a-z] - Von a bis z
🎬 Abschließend
Leistungsstarke Zeichenkettenverarbeitung mit regulären Ausdrücken!
Kernpunkte:
✅ Muster mit Regex() erstellen
✅ Vollständiger Abgleich mit matches()
✅ Teilabgleich mit find()
✅ Ersetzung mit replace()
✅ Leistungssteigerung durch Muster-Wiederverwendung
Nächster Schritt: Erstellen Sie Kotlin-typische APIs mit DSL!