【问题标题】:split string between 2 char based index在 2 个基于字符的索引之间拆分字符串
【发布时间】:2021-11-15 13:56:29
【问题描述】:

我们如何在 Kotlin 中分割两个字符之间的文本?

示例字符串:

base_id:94, user_id: 320903, is_Active=1

我只想获取 user_id 所以“320903”。但我做不到。

【问题讨论】:

  • 那个字符串到底是从哪里来的?这里的格式看起来很不一致(: vs =,空格等)。似乎它想要看起来像 JSON 而不是 JSON。你肯定可以用子字符串来解析它,但是如果你要这样做的话,应该考虑格式的稳定性
  • @Joffrey 感谢您的评论。不幸的是,我无法改变这种糟糕的格式。是的,我可以使用 subString() 但可以更改 user_id 数字。我尝试通过查找第二个“:”和第二个“,”之间的 id 来获取此字符串。它会起作用,但我做不到。
  • 顺便说一句,你的 user_id 总是 6 位数字吗?
  • @ArpitShukla 没有数字可以更改

标签: android string kotlin split


【解决方案1】:

获取它的一种方法是使用正则表达式,您可以对其进行自定义以覆盖 base_id 和 is_Active

val pattern = Pattern.compile("user_id: (?<id>[0-9]+)")
val matcher = pattern.matcher(text)
if (matcher.find()) {
    val group = matcher.group("id").trim()
    println(group)
}

输出将是:320903

或者你可以只用 split 来做到这一点,你会得到相同的结果

val items = text.split(",")
val userId = items[1].split(":")[1].trim()
println(userId)

这将在您的示例中正常工作,但请确保但对于其他情况,您可能需要自定义它或给我们提供许多示例来涵盖它们

您可以使用一个支持可选空格和 : 或 = 的函数来处理这 3 个值

fun getValueByTagName(text : String, tag : String) : String {
    val pattern = Pattern.compile("$tag[:=][ ]*(?<id>[0-9]+)")
    val matcher = pattern.matcher(text)
    return if (matcher.find())
        matcher.group("id").trim()
    else ""
}

使用它

println(getValueByTagName(text, "base_id"))      // 94
println(getValueByTagName(text, "user_id"))      // 320903
println(getValueByTagName(text, "is_Active"))    // 1

【讨论】:

  • 这里的匹配器实现没有多大意义,为什么不直接使用正确的组而不是取整个匹配(组0)并手动拆分呢?此外,OP 还没有明确字符串的格式,所以这个空格可能是可选的,冒号可能是 = 有时我们所知道的
  • 是的,你是对的,空格可能是可选的,而且 = 和 : 因为我说过这个解决方案可以与示例一起使用,但是您需要明确的规则来自定义它
  • 谢谢。这种格式是恒定的。永远都是这样。那么按照第二种方式是最好的方式吗?
  • @AmrDeveloper 我并不是说整个正则表达式方法是错误的。我是说在整个匹配组上使用split() 的这个具体实现是浪费的。在正则表达式中使用() 并直接访问正确的组会更好
  • Id 因为我用 id 命名了这个组 -> ?&lt;id&gt;[0-9]+) 这是我们想要的数字,我通过 Regex Named Groups 搜索了这个受 @Joffrey 评论启发的功能
【解决方案2】:

另一种解决方案:

方法 1:如果您的字符串与示例中显示的格式完全相同

val indexOfUserId = s.indexOf("user_id") // find index of the substring "user_id"
val end = s.indexOf(',', indexOfUserId) // find index of ',' after user_id
val userId s.substring(indexOfUserId + 9, end) // take the substring assuming that userId starts exactly 9 characters after the "u" in "user_id"

方法 2:如果您的格式可以变化(空格和符号)。还假设 user_id 始终是一个数字。

val indexOfUserId = s.indexOf("user_id")
val start = s.findAnyOf(List(10) { "$it" }, indexOfUserId)!!.first // find the first digit after "user_id"
val userId = s.substring(start).takeWhile { it.isDigit() } // start from the first digit and continue as long as you are getting digits

这里,List(10) { "$it" } 只是字符串格式的所有数字的列表,findAnyOf

从指定的 [startIndex] 开始,查找此 char 序列中任何指定 [strings] 的第一个匹配项

Try it yourself

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 2011-11-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多