使用正则表达式在Kotlin中解析字符串。
#kotlin #android #mobile #tristan

目录

  1. What we are doing
  2. Regular expressions
  3. Mapping to the data class

代码

简介

  • 我已经开始了我的下一个应用程序,这是一个Twitch客户端应用。这个系列将是我创建此应用时所面临的所有笔记和问题。

我们在做什么

  • 所以,当您将Twitch的IRC服务器连接到用户发送的每条消息时,您将获得一串,看起来像这样:

"@badge-info=subscriber/77;badges=subscriber/36,sub-gifter/50;client-nonce=d7a543c7dc514886b439d55826eeeb5b;color=;display-name=namers_namers;emotes=;first-msg=0;flags=;id=fd594314-969b-4f5e-a83f-5e2f74261e6c;mod=0;returning-chatter=0;room-id=19070311;subscriber=1;tmi-sent-ts=1690747946900;turbo=0;user-id=144252234;user-type= :marc_malabanan!marc_malabanan@marc_malabanan.tmi.twitch.tv PRIVMSG #a_seagull :LOL"

  • 我们希望能够解析该字符串并将其变成类似的数据类对象:
data class TwitchUserData(
    val badgeInfo: String?,
    val badges: String?,
    val clientNonce: String?,
    val color: String?,
    val displayName: String?,
    val emotes: String?,
    val firstMsg: String?,
    val flags: String?,
    val id: String?,
    val mod: String?,
    val returningChatter: String?,
    val roomId: String?,
    val subscriber: Boolean,
    val tmiSentTs: Long?,
    val turbo: Boolean,
    val userId: String?,
    val userType: String?
)
  • 数据类将使重新创建Twitch UI变得容易得多

  • 我们可以在正则表达式的帮助下

正则表达式

  • 如果您以上看文本,我们必须解析,您会注意到它遵循characters = characters ;的模式。因此,我们必须建立一个正则表达式以表示该模式。长话短说,代码看起来像这样:
val pattern = "([^;@]+)=([^;]+)".toRegex()
    val matchResults = pattern.findAll(input)
  • 我想指出的主要内容是

  • 1) [^;@]+这就是如何说匹配所有字符(不包括;@)。 +我们将匹配这个或多次

  • 2) =这是一个字面角色匹配。我们是说我们想匹配一个平等的标志。

  • 3) [^;]+与第一个结果相似,这就是我们匹配等同标志后出现的所有字符的方式。减去;

  • 4) brackets ()我们使用括号来形成所谓的捕获组。当我们必须将映射到我们的数据类中时,这将很有用。只需知道它使我们能够轻松地识别符号符号之前和之后的字符。这将很重要

  • 为了易于使用,我们可以将Sequence<MatchResult>使用以通过pattern.findAll(input)方法使用,然后将其转换为这样的地图:

fun parseStringBaby(input: String): Map<String, String> {
    val pattern = "([^;@]+)=([^;]+)".toRegex()
    val matchResults = pattern.findAll(input)

    val parsedData = mutableMapOf<String, String>()


    for (matchResult in matchResults) {
        val (key, value) = matchResult.destructured
        parsedData[key] = value
    }

    return parsedData
}

  • 注意val (key, value) = matchResult.destructured。这就是我们如何访问与早期括号建立的捕获组的方式。

  • 现在,我们可以轻松地绘制此地图并将其映射到我们的Twitchuserdata类

映射到数据类

  • 将解析的数据映射到我们的数据类中:
fun mapToTwitchUserData(parsedData: Map<String, String>): TwitchUserData {
return TwitchUserData(
    badgeInfo = parsedData["badge-info"],
    badges = parsedData["badges"],
    clientNonce = parsedData["client-nonce"],
    color = parsedData["color"],
    displayName = parsedData["display-name"],
    emotes = parsedData["emotes"],
    firstMsg = parsedData["first-msg"],
    flags = parsedData["flags"],
    id = parsedData["id"],
    mod = parsedData["mod"],
    returningChatter = parsedData["returning-chatter"],
    subscriber = parsedData["subscriber"]?.toIntOrNull() == 1,
    roomId = parsedData["room-id"],
    tmiSentTs = parsedData["tmi-sent"]?.toLongOrNull(),
    turbo = parsedData["turbo"]?.toIntOrNull() == 1,
    userType = parsedData["user-type"],
    userId = parsedData["user-id"],
)
}

  • 是最雄辩的代码吗?不,但是它有效。

  • 一起运行代码看起来像这样:

val parsedData = parseStringBaby(inputString)
val mappedData =mapToTwitchUserData(parsedData)

结论

  • 感谢您抽出宝贵的时间阅读我的博客文章。如果您有任何疑问或疑虑,请在下面发表评论或在Twitter上与我联系。