改进Kotlin中的查找和替换字符串

pbpqsu0x  于 2023-08-06  发布在  Kotlin
关注(0)|答案(2)|浏览(140)

我有这样的绳子

val message = "Hello, How are you? My Name is <b>Xyz</b>. <b>Abc</b> your next score will be 100 to win the game."

字符串
我想找到<b></b>之间的字符串。所以我做了一个像这样的图案

private const val BOLD_PATTERN = "<b>(.*?)</b>"


我试着搜索了一下,得到了结果。现在我想从主字符串中删除这个<b></b>。我做到了,没有任何问题

private const val BOLD_PATTERN = "<b>(.*?)</b>"
fun main() {
    val message = "Hello, How are you? My Name is <b>Xyz</b>. <b>Abc</b> your next score will be 100 to win the game."
    val itemList = findAndGetBoldList(message)
    val filterMessage = message.replace("<b>", "").replace("</b>", "")
    itemList.forEach { println("Bold part is :- $it") }
    println(filterMessage)
}

fun findAndGetBoldList(message: String): List<String> {
    return BOLD_PATTERN
        .toRegex()
        .findAll(message)
        .map {
            it.value.replace("<b>", "").replace("</b>", "")
        }
        .toList()
}

输出

Bold part is :- Xyz
Bold part is :- Abc
Hello, How are you? My Name is Xyz. Abc your next score will be 100 to win the game.


我的问题是我们能改进这种习惯用法吗?
谢啦,谢啦

uemypmqf

uemypmqf1#

我们可以稍微简化你的方法。

fun String.extractBoldItems(): Pair<String, List<String>> {
    val boldItems = mutableListOf<String>()
    val filteredMessage = replace(BOLD_PATTERN.toRegex()) {
        boldItems.add(it.groupValues[1])
        it.value.replace(Regex("<(/)?b>"), "")
    }
    return filteredMessage to boldItems
}

字符串
使用示例:

fun main() {
        val message = "Hello, How are you? My Name is <b>Xyz</b>. <b>Abc</b> your next score will be 100 to win the game."

        val (filterMessage, itemList) = message.extractBoldItems()

        itemList.forEach { println("Bold part is :- $it") }
        println(filterMessage)
    }

pbgvytdp

pbgvytdp2#

1.private const val BOLD_PATTERN = "<b>(.*?)</b>"

编译一次常量模式可以获得更好的性能,而不是每次调用函数时都编译相同的内容。于是:

private const val BOLD_REGEX = "<b>(.*?)</b>".toRegex()

字符串
但是,您不希望将这些标记作为匹配的一部分,因此可以使用positive lookbehind and positive lookahead将它们排除在外。此外,标记不区分大小写。使用下面的正则表达式,你可以遍历你的匹配,而不必删除标签:

private val BOLD_REGEX = "(?<=<b>).*?(?=</b>)".toRegex(RegexOption.IGNORE_CASE)
...
fun findAndGetBoldList(message: String): List<String> {
    return BOLD_REGEX
        .findAll(message)
        .map {
            it.value
        }
        .toList()
}

2.val filterMessage = message.replace("<b>", "").replace("</b>", "")

同样,您应该根据不区分大小写的匹配进行筛选。你也可以通过一个简单的调用来替换:

private val REMOVE_BOLD_TAG_REGEX = "</?b>".toRegex(RegexOption.IGNORE_CASE)
...
    val filterMessage = message.replace(REMOVE_BOLD_TAG_REGEX, "")

完整代码:

private val BOLD_REGEX = "(?<=<b>).*?(?=</b>)".toRegex(RegexOption.IGNORE_CASE)
private val REMOVE_BOLD_TAG_REGEX = "</?b>".toRegex(RegexOption.IGNORE_CASE)

fun main() {
    val message = "Hello, How are you? My Name is <b>Xyz</b>. <b>Abc</b> your next score will be 100 to win the game."
    val itemList = findAndGetBoldList(message)
    val filterMessage = message.replace(REMOVE_BOLD_TAG_REGEX, "")
    itemList.forEach { println("Bold part is :- $it") }
    println(filterMessage)
}

fun findAndGetBoldList(message: String): List<String> {
    return BOLD_REGEX
        .findAll(message)
        .map {
            it.value
        }
        .toList()
}

相关问题