news 2026/5/9 6:14:14

正则表达式及其常见使用(Kotlin版)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
正则表达式及其常见使用(Kotlin版)

✅作者简介:大家好,我是 Meteors.,技术爱好者,持续分享编程内容
🍎个人主页:Meteors.的博客
💞当前专栏:知识分享
✨特色专栏:知识分享
🥭本文内容:正则表达式及其常见使用
📚 **ps*** :阅读这篇文章如果有问题或者疑惑,欢迎各位在评论区提出!


目录

一、背景介绍

二、常见用处

三、核心语法规则

1. 特殊语法

2. 字符集

四、Kotlin中的Regex类

1. 创建Regex对象

五、核心操作方法

1. 匹配整个字符串

2. 查找匹配项

3. 查找并提取分组

4. 替换文本

5. 分割字符串

6. 检查是否包含匹配

六、高级用法

1. 命名捕获组

2. 多行模式和忽略大小写

3. 使用边界匹配

4. 懒惰匹配(非贪婪模式)

六、实际应用示例

1. 验证各种格式

2. 敏感词过滤

3. 日志解析

七、性能优化建议


一、背景介绍

最近在10几万条的日志中搜索有用信息,又或者在输入框中过滤特殊字符,都有用到正则表达式最,可是由于都不太熟练,需要上网进行搜索。于是结合网上的一些资料,编写了这篇博客,用于巩固和做备份。


二、常见用处

正则表达式(Regular Expression)是一种用于匹配字符串模式的强大工具,主要用于:

  • 验证输入格式(邮箱、手机号等)

  • 搜索和提取文本内容

  • 替换特定模式的文本

  • 分割字符串


三、核心语法规则

1. 特殊语法

. // 匹配任意单个字符(除换行符) ^ // 匹配字符串开始 $ // 匹配字符串结束 * // 匹配前一个元素0次或多次 + // 匹配前一个元素1次或多次 ? // 匹配前一个元素0次或1次 {n} // 精确匹配n次 {n,} // 至少匹配n次 {n,m} // 匹配n到m次 | // 或运算符 () // 分组 [] // 字符集 \d // 数字,等价于[0-9] \D // 非数字 \w // 单词字符,等价于[a-zA-Z0-9_] \W // 非单词字符 \s // 空白字符 \S // 非空白字符

2. 字符集

[abc] // 匹配a、b或c [^abc] // 匹配除a、b、c外的字符 [a-z] // 匹配a到z的小写字母 [a-zA-Z] // 匹配所有字母 [0-9] // 匹配数字

四、Kotlin中的Regex类

Kotlin通过Regex类提供正则表达式支持,有两种创建方式:

1. 创建Regex对象

// 方式1:使用构造函数 val regex1 = Regex("""\d+""") // 原始字符串,推荐 // 方式2:使用字符串扩展函数 val regex2 = "\\d+".toRegex() // 方式3:使用编译选项 val regex3 = Regex("pattern", RegexOption.IGNORE_CASE)

注意:在Kotlin中推荐使用三引号原始字符串"""...""",避免转义反斜杠的麻烦。


五、核心操作方法

1. 匹配整个字符串

val emailRegex = """^\w+@[a-zA-Z_]+?\.[a-zA-Z]{2,3}$""".toRegex() fun validateEmail(email: String): Boolean { return email.matches(emailRegex) } // 使用 println(validateEmail("test@example.com")) // true println(validateEmail("invalid-email")) // false

2. 查找匹配项

fun findNumbers(text: String): List<String> { val numberRegex = """\d+""".toRegex() return numberRegex.findAll(text).map { it.value }.toList() } // 使用 val text = "订单号:12345,金额:678元" println(findNumbers(text)) // [12345, 678]

3. 查找并提取分组

fun extractDateInfo(dateStr: String): Triple<String, String, String>? { val regex = """(\d{4})-(\d{2})-(\d{2})""".toRegex() val match = regex.find(dateStr) ?: return null // group(0)是整个匹配,group(1)开始是捕获组 return Triple( match.groupValues[1], // 年 match.groupValues[2], // 月 match.groupValues[3] // 日 ) } // 使用 val result = extractDateInfo("今天日期是2024-01-15") println(result) // (2024, 01, 15)

4. 替换文本

fun maskPhoneNumber(phone: String): String { val regex = """(\d{3})\d{4}(\d{4})""".toRegex() return regex.replace(phone, "$1****$2") // $1和$2引用捕获组 } // 使用 println(maskPhoneNumber("13812345678")) // 138****5678

5. 分割字符串

fun splitByPunctuation(text: String): List<String> { val regex = """[,.;!?]""".toRegex() return text.split(regex) } // 使用 val words = splitByPunctuation("Hello,world!How are you?") println(words) // [Hello, world, How are you]

6. 检查是否包含匹配

fun containsUrl(text: String): Boolean { val urlRegex = """https?://[^\s]+""".toRegex() return urlRegex.containsMatchIn(text) } // 使用 println(containsUrl("访问 https://example.com 了解更多")) // true

六、高级用法

1. 命名捕获组

fun parseLogLine(log: String): Map<String, String> { val regex = """(?<timestamp>\d{4}-\d{2}-\d{2}) (?<level>\w+): (?<message>.+)""".toRegex() val match = regex.find(log) ?: return emptyMap() return match.groups as? Map<String, String> ?: emptyMap() } // 使用 val log = "2024-01-15 ERROR: 数据库连接失败" val parsed = parseLogLine(log) println(parsed["timestamp"]) // 2024-01-15

2. 多行模式和忽略大小写

val multiLineRegex = """^start.*end$""".toRegex( setOf(RegexOption.MULTILINE, RegexOption.IGNORE_CASE) ) val text = """ start first END middle start second End """.trimIndent() println(multiLineRegex.findAll(text).count()) // 2

3. 使用边界匹配

fun findWholeWord(text: String, word: String): List<String> { // \b 表示单词边界 val regex = """\b$word\b""".toRegex(RegexOption.IGNORE_CASE) return regex.findAll(text).map { it.value }.toList() } // 使用 val result = findWholeWord("cat catalog scatter", "cat") println(result) // [cat] (不会匹配到catalog和scatter中的cat)

4. 懒惰匹配(非贪婪模式)

fun extractHtmlTag(html: String, tagName: String): String? { // *? 表示非贪婪匹配,尽可能少地匹配字符 val regex = """<$tagName>.*?</$tagName>""".toRegex() return regex.find(html)?.value } // 使用 val html = "<div>内容1</div><div>内容2</div>" println(extractHtmlTag(html, "div")) // <div>内容1</div>

六、实际应用示例

1. 验证各种格式

object Validator { // 手机号(中国) private val phoneRegex = """^1[3-9]\d{9}$""".toRegex() // 邮箱 private val emailRegex = """^[\w.-]+@[\w.-]+\.[a-zA-Z]{2,}$""".toRegex() // 身份证号(18位) private val idCardRegex = """^\d{17}[\dXx]$""".toRegex() // URL private val urlRegex = """^https?://[^\s/$.?#].[^\s]*$""".toRegex() // IPv4地址 private val ipv4Regex = """^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$""".toRegex() fun isValidPhone(phone: String) = phone.matches(phoneRegex) fun isValidEmail(email: String) = email.matches(emailRegex) fun isValidIdCard(idCard: String) = idCard.matches(idCardRegex) fun isValidUrl(url: String) = url.matches(urlRegex) fun isValidIpv4(ip: String): Boolean { if (!ip.matches(ipv4Regex)) return false return ip.split(".").all { it.toInt() in 0..255 } } }

2. 敏感词过滤

class SensitiveFilter(private val sensitiveWords: List<String>) { private val regex by lazy { // 构建或模式,如:\b(词1|词2|词3)\b val pattern = sensitiveWords.joinToString("|") { Regex.escape(it) } """\b($pattern)\b""".toRegex(RegexOption.IGNORE_CASE) } fun filter(text: String, replacement: String = "***"): String { return regex.replace(text, replacement) } fun hasSensitiveWord(text: String): Boolean { return regex.containsMatchIn(text) } } // 使用 val filter = SensitiveFilter(listOf("广告", "诈骗", "违规")) val text = "这是一条广告信息,不要信" println(filter.filter(text)) // 这是一条***信息,不要信

3. 日志解析

data class LogEntry( val timestamp: String, val level: String, val thread: String, val className: String, val message: String ) fun parseLog(log: String): LogEntry? { val regex = """(\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2},\d{3})\s+(\w+)\s+\[([^\]]+)\]\s+([\w.]+)\s+(.+)""" .toRegex() val match = regex.find(log) ?: return null return LogEntry( timestamp = match.groupValues[1], level = match.groupValues[2], thread = match.groupValues[3], className = match.groupValues[4], message = match.groupValues[5] ) }

七、性能优化建议

  • 预编译Pattern:复用Regex对象,避免重复创建

  • 使用原始字符串:三引号字符串避免双重转义

  • 避免过度使用捕获组:不需要提取的内容使用非捕获组(?:...)

  • 警惕灾难性回溯:避免嵌套的量词如(a*)*

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/2 13:18:27

SELinux管理效率提升300%的7个AI技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 开发一个SELinux策略优化分析工具&#xff0c;能够自动识别冗余规则、冲突策略和过度权限配置。工具应包含策略静态分析引擎和运行时监控模块&#xff0c;提供可视化策略依赖关系图…

作者头像 李华
网站建设 2026/5/1 14:29:58

AnimeGANv2如何应对网络波动?断点续传部署策略

AnimeGANv2如何应对网络波动&#xff1f;断点续传部署策略 1. 背景与挑战&#xff1a;轻量级AI模型的部署稳定性需求 随着AI图像风格迁移技术的普及&#xff0c;AnimeGANv2因其极小的模型体积&#xff08;仅8MB&#xff09; 和高质量的动漫风格生成能力&#xff0c;成为个人开…

作者头像 李华
网站建设 2026/5/1 10:28:52

比手动编码快10倍:Object.assign自动化技巧

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容&#xff1a; 生成一个性能对比工具&#xff1a;1. 传统for-in循环实现对象合并 2. 手动展开运算符实现 3. Object.assign实现。要求使用Kimi-K2模型自动生成三种方案的代码&#xff0c;并添加B…

作者头像 李华
网站建设 2026/5/1 7:01:15

STM32CubeMX打不开全解析:适合新手的系统学习

STM32CubeMX打不开&#xff1f;别慌&#xff0c;带你从零排查每一个细节 你是不是也遇到过这种情况&#xff1a;兴冲冲下载好STM32CubeMX&#xff0c;双击图标准备开始你的嵌入式开发之旅&#xff0c;结果—— 什么都没发生 。 没有窗口、没有提示、任务管理器里进程一闪而…

作者头像 李华
网站建设 2026/5/3 8:04:43

AnimeGANv2商业授权说明:企业使用合规部署指南

AnimeGANv2商业授权说明&#xff1a;企业使用合规部署指南 1. 引言 随着AI技术的快速发展&#xff0c;风格迁移在图像处理领域的应用日益广泛。AnimeGANv2作为一款轻量高效的照片转二次元动漫模型&#xff0c;凭借其出色的画质表现和低资源消耗&#xff0c;已被广泛应用于个人…

作者头像 李华
网站建设 2026/5/3 8:13:35

开源TTS新选择:VibeVoice长文本语音合成入门必看

开源TTS新选择&#xff1a;VibeVoice长文本语音合成入门必看 1. 技术背景与核心挑战 在当前人工智能语音合成领域&#xff0c;长文本、多说话人场景的应用需求日益增长。传统文本转语音&#xff08;TTS&#xff09;系统虽然在单人短句合成上表现优异&#xff0c;但在处理长篇…

作者头像 李华