用REGEX Group的Index从数组中替换所有Regex出现

发布于 2025-02-12 12:57:07 字数 607 浏览 1 评论 0原文

我有文本:

lorem ipsum%name0%dolor sit amet%name1%,consectetur%name2%adipiscising elit。

和array names : [BOB,ALICE,TOM]

我需要从%namex% X索引,然后替换所有%name0%%name1%%name2%带有来自数组的相应项目:names.get(x)

我有

private fun String.replaceWithNames(names: List<String>): String {
    var result = this
    names.forEachIndexed { index, s ->
        result = result.replace("%NAME$index%", s)
    }
    return result
}

,但我相信它可以更优化。

I have text:

Lorem ipsum %NAME0% dolor sit amet %NAME1%, consectetur %NAME2% adipiscing elit.

and array names:
[Bob, Alice, Tom]

I need to get X index from %NAMEX% and replace all %NAME0%, %NAME1%, %NAME2% with corresponding item from array: names.get(X).

I have

private fun String.replaceWithNames(names: List<String>): String {
    var result = this
    names.forEachIndexed { index, s ->
        result = result.replace("%NAME$index%", s)
    }
    return result
}

but I am sure that it can be done more optimally.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

北恋 2025-02-19 12:57:07

您可以使用正则罚款仅通过一次字符串,并使用最后一个 regex.replace 超载(带有lambda)。另外,我添加了一些验证,以防有一个不限制索引的名称参考(您的当前代码只会将参考留在那里)。

private val nameRefRegex = Regex("""%NAME(\d)%""")

private fun String.replaceWithNames(names: List<String>): String {
    return nameRefRegex.replace(this) { match ->
        val index = match.groupValues[1].toInt()
        require(index in names.indices) { "Invalid name index $index, only ${names.size} names available" }
        names[index]
    }
}

注意:如果您需要10个以上的名称,则可以将(\ d)更改为(\ d+)在REGEX中(以支持1位以上)

You could use a regex to go through the string only once and replace each value using the last Regex.replace overload (with lambda). Also, I added some validation in case there is a name reference with an out of bounds index (your current code would just leave the reference there).

private val nameRefRegex = Regex("""%NAME(\d)%""")

private fun String.replaceWithNames(names: List<String>): String {
    return nameRefRegex.replace(this) { match ->
        val index = match.groupValues[1].toInt()
        require(index in names.indices) { "Invalid name index $index, only ${names.size} names available" }
        names[index]
    }
}

Note: if you need more than 10 names, you could change (\d) to (\d+) in the regex (to support more than 1 digit)

独留℉清风醉 2025-02-19 12:57:07

您可以根据 kotlin.text.text.text.text.text .replace 函数:

val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return this.replace(pattern, fun(m: MatchResult) : String { 
        return names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    })
}

或者,

val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return pattern.replace(this) { m ->
        names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    }
}

请参阅在线kotlin demo

import java.util.*
 
val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return pattern.replace(this) { m ->
        names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    }
}
 
fun main(args: Array<String>) {
    val lst = listOf("Bob", "Alice", "Tom")
    println( "Lorem ipsum %NAME0% dolor sit amet %NAME1%, consectetur %NAME2% adipiscing elit. Wrong %NAME11%".replaceWithNames(lst) )
}

output:

Lorem ipsum Bob dolor sit amet Alice, consectetur Tom adipiscing elit. Wrong %NAME11%

%name(\ d+)%(\ d+)% regex Matches %name,然后将一个或多个数字捕获到第1组中,然后匹配 char。

如果名称包含第1组中捕获的索引,则替换是相应的名称项目,否则,这是整个匹配项。

You can use the following based on the kotlin.text.replace function:

val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return this.replace(pattern, fun(m: MatchResult) : String { 
        return names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    })
}

Or,

val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return pattern.replace(this) { m ->
        names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    }
}

See the online Kotlin demo:

import java.util.*
 
val pattern = """%NAME(\d+)%""".toRegex()
fun String.replaceWithNames(names: List<String>): String {
    return pattern.replace(this) { m ->
        names.getOrNull(m.groupValues[1].toInt()) ?: m.value
    }
}
 
fun main(args: Array<String>) {
    val lst = listOf("Bob", "Alice", "Tom")
    println( "Lorem ipsum %NAME0% dolor sit amet %NAME1%, consectetur %NAME2% adipiscing elit. Wrong %NAME11%".replaceWithNames(lst) )
}

Output:

Lorem ipsum Bob dolor sit amet Alice, consectetur Tom adipiscing elit. Wrong %NAME11%

The %NAME(\d+)% regex matches %NAME, then captures one or more digits into Group 1, and then matches a % char.

If names contains the index captured in Group 1, the replacement is the corresponding names item, else, it is the whole match.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文