You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Kotlin中如何高效实现电话号码字符串格式化?

Better Ways to Format Russian Phone Numbers in Kotlin

Great question! Your current implementation gets the job done, but all those chained drop calls make the logic hard to follow and create unnecessary intermediate strings—definitely not ideal for readability or efficiency. Let's look at two cleaner, more robust alternatives that fix both issues.

Option 1: Regular Expression Replacement (Concise & Readable)

If you value clean, straightforward code, a regex replacement is perfect here. Since your target format follows a fixed pattern (1-digit country code, 3-digit region code, 3 digits, 2 digits, 2 digits), we can split the input into groups and rearrange them directly:

private fun formatPhone(phone: String): String {
    // Validate input to avoid runtime errors
    require(phone.length == 11 && phone.all { it.isDigit() }) {
        "Phone number must be an 11-digit string of digits"
    }
    
    // Use regex to group digits and format them
    return phone.replace(Regex("(\\d)(\\d{3})(\\d{3})(\\d{2})(\\d{2})"), "+$1 $2 $3-$4-$5")
}

How this works:

  • The regex (\\d)(\\d{3})(\\d{3})(\\d{2})(\\d{2}) splits the 11-digit number into 5 capture groups:
    1. The first digit (country code: 7)
    2. Next 3 digits (region code: 999)
    3. Next 3 digits: 888
    4. Next 2 digits: 66
    5. Last 2 digits: 66
  • The replacement string +$1 $2 $3-$4-$5 rearranges these groups into your desired format.
  • The require check ensures we only process valid input, preventing index out-of-bounds errors or malformed output.

Option 2: Direct Substring Extraction (Maximum Efficiency)

If you need top-tier performance (e.g., processing thousands of phone numbers), using substring instead of drop is far more efficient. Unlike drop, which creates a new string each time, substring references the original string's character array—no extra memory allocations for intermediate strings:

private fun formatPhone(phone: String): String {
    require(phone.length == 11 && phone.all { it.isDigit() }) {
        "Phone number must be an 11-digit string of digits"
    }
    
    val countryCode = phone.substring(0, 1)
    val regionCode = phone.substring(1, 4)
    val firstSub = phone.substring(4, 7)
    val secondSub = phone.substring(7, 9)
    val thirdSub = phone.substring(9)
    
    return "+$countryCode $regionCode $firstSub-$secondSub-$thirdSub"
}

Why this beats your original code:

  • Each substring call directly targets the exact range you need, making the logic instantly readable (no more mental math to decode dropLast(7).drop(1)).
  • It eliminates the multiple intermediate strings created by repeated drop calls, saving memory and speeding up execution.

Which to Choose?

  • Go with the regex approach if code brevity and readability are your top priorities. It’s easy to adjust if you ever need to support similar number formats.
  • Use the substring approach if performance is critical (e.g., batch processing large datasets). It’s slightly more verbose but has minimal overhead.

Both solutions are far more maintainable and efficient than your original implementation, plus they include input validation to catch bad data early.

内容的提问来源于stack exchange,提问作者onesector

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 22:07:50